Highly experimental DS3 support added. Use newly added features at your own risk. Requires libusb installed and DS3 set up as per instructions at http://forums.pcsx2.net/thread-7582.html. Doesn't require sixaxis64.exe/sixaxis.exe, but might have to fool around with starting/stopping Pcsx2 or LilyPad's test device screen and the PS button on your controller until the "1" light turns on.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1810 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
mattmenke 2009-09-12 13:10:17 +00:00
parent 179054c1a0
commit 73cace2e54
17 changed files with 918 additions and 54 deletions

View File

@ -14,6 +14,7 @@
#include "InputManager.h"
#include "KeyboardQueue.h"
#include "WndProcEater.h"
#include "DualShock3.h"
// Needed to know if raw input is available. It requires XP or higher.
#include "RawInput.h"
@ -48,6 +49,7 @@ const GeneralSettingsBool BoolOptionsInfo[] = {
{L"DirectInput Game Devices", IDC_G_DI, 1},
{L"XInput", IDC_G_XI, 1},
{L"DualShock 3", IDC_G_DS3, 0},
{L"Multitap 1", IDC_MULTITAP1, 0},
{L"Multitap 2", IDC_MULTITAP2, 0},
@ -151,8 +153,15 @@ void RefreshEnabledDevices(int updateDeviceList) {
(dev->type == MOUSE && dev->api == config.mouseApi) ||
(dev->type == OTHER &&
((dev->api == DI && config.gameApis.directInput) ||
(dev->api == DS3 && config.gameApis.dualShock3) ||
(dev->api == XINPUT && config.gameApis.xInput)))) {
dm->EnableDevice(i);
if (config.gameApis.dualShock3 && dev->api == DI && dev->displayName &&
!wcsnicmp(dev->displayName+3, L"PLAYSTATION(R)3", 15)) {
dm->DisableDevice(i);
}
else {
dm->EnableDevice(i);
}
}
else
dm->DisableDevice(i);
@ -1485,6 +1494,9 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
}
dm->Update(&info);
dm->PostRead();
Sleep(150);
dm->Update(&info);
dm->PostRead();
dev->SetEffect(ffb, 255);
SetTimer(hWnd, 1, 3000, 0);
}
@ -1712,6 +1724,11 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L
RefreshEnabledDevicesAndDisplay(0, hWnd, 0);
UpdatePadList(hWnd);
if (!DualShock3Possible()) {
config.gameApis.dualShock3 = 0;
EnableWindow(GetDlgItem(hWnd, IDC_G_DS3), 0);
}
for (int j=0; j<sizeof(BoolOptionsInfo)/sizeof(BoolOptionsInfo[0]); j++) {
CheckDlgButton(hWnd, BoolOptionsInfo[j].ControlId, BST_CHECKED * config.bools[j]);
}
@ -1819,6 +1836,21 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L
int mtap = config.multitap[0] + 2*config.multitap[1];
if (IsDlgButtonChecked(hWnd, IDC_G_DS3) && !config.gameApis.dualShock3) {
if (IDOK !=
MessageBoxA(hWnd,
"This open will attempt to connect directly to any connected\n"
"DualShock 3 devices. It is completely experimental, and based\n"
"on no published specs.\n"
"Furthermore, It uses libusb to Initialize DS3 pads. Libusb can\n"
"do odd things to USB and non-USB devices when it enumerates them.\n"
"I have no idea if it works with bluetooth or not.\n"
"Are you sure you wish to continue?", "Warning", MB_OKCANCEL | MB_ICONWARNING)) {
CheckDlgButton(hWnd, IDC_G_DS3, BST_UNCHECKED);
}
}
for (int j=0; j<sizeof(BoolOptionsInfo)/sizeof(BoolOptionsInfo[0]); j++) {
config.bools[j] = (IsDlgButtonChecked(hWnd, BoolOptionsInfo[j].ControlId) == BST_CHECKED);
}

View File

@ -39,6 +39,7 @@ public:
struct {
u8 directInput;
u8 xInput;
u8 dualShock3;
} gameApis;
u8 multitap[2];

View File

@ -6,6 +6,8 @@
#include "KeyboardHook.h"
#include "RawInput.h"
#include "XInput.h"
#include "HidDevice.h"
#include "DualShock3.h"
void EnumDevices(int hideDXXinput) {
// Needed for enumeration of some device types.
@ -13,6 +15,7 @@ void EnumDevices(int hideDXXinput) {
InputDeviceManager *oldDm = dm;
dm = new InputDeviceManager();
EnumDualShock3s();
EnumHookDevices();
EnumWindowsMessagingDevices();
EnumRawInputDevices();

View File

@ -243,7 +243,7 @@ public:
memset(&dieffect, 0, sizeof(dieffect));
dieffect.dwSize = sizeof(dieffect);
dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS;
dieffect.dwDuration = 2000000;
dieffect.dwDuration = 1000000;
dieffect.dwGain = 10000;
dieffect.dwTriggerButton = DIEB_NOTRIGGER;
union {

View File

@ -0,0 +1,390 @@
#include "Global.h"
#include <time.h>
#include "usb.h"
#include "HidDevice.h"
#include "InputManager.h"
#define VID 0x054c
#define PID 0x0268
#define CHECK_DELAY 5
time_t lastDS3Check = 0;
typedef void (__cdecl *_usb_init)(void);
typedef int (__cdecl *_usb_close)(usb_dev_handle *dev);
typedef int (__cdecl *_usb_get_string_simple)(usb_dev_handle *dev, int index, char *buf, size_t buflen);
typedef usb_dev_handle *(__cdecl *_usb_open)(struct usb_device *dev);
typedef int (__cdecl *_usb_find_busses)(void);
typedef int (__cdecl *_usb_find_devices)(void);
typedef struct usb_bus *(__cdecl *_usb_get_busses)(void);
typedef usb_dev_handle *(__cdecl *_usb_open)(struct usb_device *dev);
typedef int (__cdecl *_usb_control_msg)(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);
_usb_init pusb_init;
_usb_close pusb_close;
_usb_get_string_simple pusb_get_string_simple;
_usb_open pusb_open;
_usb_find_busses pusb_find_busses;
_usb_find_devices pusb_find_devices;
_usb_get_busses pusb_get_busses;
_usb_control_msg pusb_control_msg;
HMODULE hModLibusb = 0;
int DualShock3Possible();
void EnumDualShock3s();
void UninitLibUsb() {
if (hModLibusb) {
FreeLibrary(hModLibusb);
hModLibusb = 0;
}
}
void TryInitDS3(usb_device *dev) {
while (dev) {
if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) {
usb_dev_handle *handle = pusb_open(dev);
if (handle) {
char junk[20];
pusb_control_msg(handle, 0xa1, 1, 0x03f2, 0, junk, 17, 1000);
pusb_close(handle);
}
}
if (dev->num_children) {
for (int i=0; i<dev->num_children; i++) {
TryInitDS3(dev->children[i]);
}
}
dev = dev->next;
}
}
void DS3Check() {
pusb_find_busses();
pusb_find_devices();
usb_bus *bus = pusb_get_busses();
while (bus) {
TryInitDS3(bus->devices);
bus = bus->next;
}
lastDS3Check = time(0);
}
int InitLibUsb() {
if (hModLibusb) {
return 1;
}
hModLibusb = LoadLibraryA("C:\\windows\\system32\\libusb0.dll");
if (hModLibusb) {
if ((pusb_init = (_usb_init) GetProcAddress(hModLibusb, "usb_init")) &&
(pusb_close = (_usb_close) GetProcAddress(hModLibusb, "usb_close")) &&
(pusb_get_string_simple = (_usb_get_string_simple) GetProcAddress(hModLibusb, "usb_get_string_simple")) &&
(pusb_open = (_usb_open) GetProcAddress(hModLibusb, "usb_open")) &&
(pusb_find_busses = (_usb_find_busses) GetProcAddress(hModLibusb, "usb_find_busses")) &&
(pusb_find_devices = (_usb_find_devices) GetProcAddress(hModLibusb, "usb_find_devices")) &&
(pusb_get_busses = (_usb_get_busses) GetProcAddress(hModLibusb, "usb_get_busses")) &&
(pusb_control_msg = (_usb_control_msg) GetProcAddress(hModLibusb, "usb_control_msg"))) {
pusb_init();
return 1;
}
UninitLibUsb();
}
return 0;
}
int DualShock3Possible() {
return InitLibUsb();
}
#include <pshpack1.h>
struct MotorState {
unsigned char duration;
unsigned char force;
};
struct LightState {
// 0xFF makes it stay on.
unsigned char duration;
// Have to make one or the other non-zero to turn on light.
unsigned char dunno[2];
// 0 is fully lit.
unsigned char dimness;
// Have to make non-zero to turn on light.
unsigned char on;
};
// Data sent to DS3 to set state.
struct DS3Command {
unsigned char id;
unsigned char unsure;
// Big is first, then small.
MotorState motors[2];
unsigned char noClue[4];
// 2 is pad 1 light, 4 is pad 2, 8 is pad 3, 16 is pad 4. No clue about the others.
unsigned char lightFlags;
// Lights are in reverse order. pad 1 is last.
LightState lights[4];
unsigned char dunno[18];
};
#include <poppack.h>
int CharToAxis(unsigned char c) {
int v = (int)c + ((unsigned int)c >> 7);
return ((c-128) * FULLY_DOWN)>>7;
}
int CharToButton(unsigned char c) {
int v = (int)c + ((unsigned int)c >> 7);
return (v * FULLY_DOWN)>>8;
}
class DualShock3Device : public Device {
// Cached last vibration values by pad and motor.
// Need this, as only one value is changed at a time.
int ps2Vibration[2][4][2];
int vibration[2];
public:
int index;
HANDLE hFile;
DS3Command sendState;
unsigned char getState[49];
OVERLAPPED readop;
OVERLAPPED writeop;
int writeQueued;
int StartRead() {
readop.Offset = readop.OffsetHigh = 0;
int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop);
return (res || GetLastError() == ERROR_IO_PENDING);
}
int StartWrite() {
writeop.Offset = writeop.OffsetHigh = 0;
for (int i=0; i<2; i++) {
if (vibration[i]) {
sendState.motors[i].duration = 0x7F;
int force = vibration[i] * 256/FULLY_DOWN;
if (force > 255) force = 255;
sendState.motors[i].force = (unsigned char) force;
}
else {
sendState.motors[i].force = 0;
sendState.motors[i].duration = 0;
}
}
int res = WriteFile(hFile, &sendState, sizeof(sendState), 0, &writeop);
return (res || GetLastError() == ERROR_IO_PENDING);
}
DualShock3Device(int index, wchar_t *name, wchar_t *path) : Device(DS3, OTHER, name, path) {
memset(&readop, 0, sizeof(readop));
memset(&writeop, 0, sizeof(writeop));
memset(&sendState, 0, sizeof(sendState));
sendState.id = 1;
int temp = (index&4);
sendState.lightFlags = (1 << (temp+1));
sendState.lights[3-temp].duration = 0xFF;
sendState.lights[3-temp].dunno[0] = 1;
sendState.lights[3-temp].on = 1;
memset(ps2Vibration, 0, sizeof(ps2Vibration));
writeQueued = 0;
vibration[0] = vibration[1] = 0;
this->index = index;
int i;
for (i=0; i<16; i++) {
AddPhysicalControl(PSHBTN, i, 0);
}
for (; i<20; i++) {
AddPhysicalControl(ABSAXIS, i, 0);
}
AddFFAxis(L"Slow Motor", 0);
AddFFAxis(L"Fast Motor", 1);
AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT);
hFile = INVALID_HANDLE_VALUE;
}
wchar_t *GetPhysicalControlName(PhysicalControl *c) {
const static wchar_t *names[] = {
L"Square",
L"Cross",
L"Circle",
L"Triangle",
L"R1",
L"L1",
L"R2",
L"L2",
L"R3",
L"L3",
L"Left",
L"Down",
L"Right",
L"Up",
L"Start",
L"Select",
L"Left Thumb X",
L"Left Thumb Y",
L"Right Thumb X",
L"Right Thumb Y",
};
unsigned int i = (unsigned int) (c - physicalControls);
if (i < 20) {
return (wchar_t*)names[i];
}
return Device::GetPhysicalControlName(c);
}
int Activate(void *d) {
if (!lastDS3Check) {
DS3Check();
}
else {
lastDS3Check = time(0) - CHECK_DELAY+3;
}
if (active) Deactivate();
readop.hEvent = CreateEvent(0, 0, 0, 0);
writeop.hEvent = CreateEvent(0, 0, 0, 0);
hFile = CreateFileW(instanceID, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (!readop.hEvent || !writeop.hEvent || hFile == INVALID_HANDLE_VALUE ||
!StartRead() || !StartWrite()) {
Deactivate();
return 0;
}
writeQueued = 1;
active = 1;
AllocState();
return 1;
}
int Update() {
if (!active) return 0;
HANDLE h[2] = {
readop.hEvent,
writeop.hEvent
};
while (1) {
DWORD res = WaitForMultipleObjects(2, h, 0, 0);
if (res == WAIT_OBJECT_0) {
// Do stuff.
if (!StartRead()) {
Deactivate();
return 0;
}
physicalControlState[0] = CharToButton(getState[25]);
physicalControlState[1] = CharToButton(getState[24]);
physicalControlState[2] = CharToButton(getState[23]);
physicalControlState[3] = CharToButton(getState[22]);
physicalControlState[4] = CharToButton(getState[21]);
physicalControlState[5] = CharToButton(getState[20]);
physicalControlState[6] = CharToButton(getState[19]);
physicalControlState[7] = CharToButton(getState[18]);
physicalControlState[10] = CharToButton(getState[17]);
physicalControlState[11] = CharToButton(getState[16]);
physicalControlState[12] = CharToButton(getState[15]);
physicalControlState[13] = CharToButton(getState[14]);
physicalControlState[8] = ((getState[2]&4)/4) * FULLY_DOWN;
physicalControlState[9] = ((getState[2]&2)/2) * FULLY_DOWN;
physicalControlState[15] = ((getState[2]&1)/1) * FULLY_DOWN;
physicalControlState[14] = ((getState[2]&8)/8) * FULLY_DOWN;
physicalControlState[16] = CharToAxis(getState[6]);
physicalControlState[17] = CharToAxis(getState[7]);
physicalControlState[18] = CharToAxis(getState[8]);
physicalControlState[19] = CharToAxis(getState[9]);
continue;
}
else if (res == WAIT_OBJECT_0+1) {
writeQueued--;
if (writeQueued) {
if (!StartWrite()) {
Deactivate();
return 0;
}
}
}
else {
time_t test = time(0);
if (test - lastDS3Check >= CHECK_DELAY) {
DS3Check();
}
}
break;
}
return 1;
}
void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) {
ps2Vibration[port][slot][motor] = force;
vibration[0] = vibration[1] = 0;
for (int p=0; p<2; p++) {
for (int s=0; s<4; s++) {
for (int i=0; i<pads[p][s].numFFBindings; i++) {
// Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me.
ForceFeedbackBinding *ffb = &pads[p][s].ffBindings[i];
vibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
vibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
}
}
}
if (!writeQueued) {
StartWrite();
}
if (writeQueued<2) {
writeQueued++;
}
}
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {
PadBindings pBackup = pads[0][0];
pads[0][0].ffBindings = binding;
pads[0][0].numFFBindings = 1;
SetEffects(0, 0, binding->motor, 255);
pads[0][0] = pBackup;
}
void Deactivate() {
if (hFile != INVALID_HANDLE_VALUE) {
CancelIo(hFile);
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
}
if (readop.hEvent) {
CloseHandle(readop.hEvent);
}
if (writeop.hEvent) {
CloseHandle(writeop.hEvent);
}
writeQueued = 0;
memset(ps2Vibration, 0, sizeof(ps2Vibration));
vibration[0] = vibration[1] = 0;
FreeState();
active = 0;
}
~DualShock3Device() {
}
};
void EnumDualShock3s() {
if (!InitLibUsb()) return;
HidDeviceInfo *foundDevs = 0;
int numDevs = FindHids(&foundDevs, VID, PID);
if (!numDevs) return;
int index = 0;
for (int i=0; i<numDevs; i++) {
if (foundDevs[i].caps.FeatureReportByteLength == 49 &&
foundDevs[i].caps.InputReportByteLength == 49 &&
foundDevs[i].caps.OutputReportByteLength == 49) {
wchar_t temp[100];
wsprintfW(temp, L"DualShock 3 #%i", index+1);
dm->AddDevice(new DualShock3Device(index, temp, foundDevs[i].path));
index++;
}
free(foundDevs[i].path);
}
free(foundDevs);
}

View File

@ -0,0 +1,7 @@
int DualShock3Possible();
void EnumDualShock3s();
#include "InputManager.h"
// May move elsewhere in the future.
int InitLibUsb();
void UninitLibUsb();

View File

@ -20,6 +20,8 @@ typedef void (__stdcall *_HidD_GetHidGuid) (GUID* HidGuid);
typedef BOOLEAN (__stdcall *_HidD_GetPreparsedData) (HANDLE HidDeviceObject, HIDP_PREPARSED_DATA **PreparsedData);
typedef NTSTATUS (__stdcall *_HidP_GetCaps) (HIDP_PREPARSED_DATA* PreparsedData, HIDP_CAPS *caps);
typedef BOOLEAN (__stdcall *_HidD_FreePreparsedData) (HIDP_PREPARSED_DATA *PreparsedData);
typedef BOOLEAN (__stdcall *_HidD_GetFeature) (HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
typedef BOOLEAN (__stdcall *_HidD_SetFeature) (HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
GUID GUID_DEVINTERFACE_HID;
_HidD_GetHidGuid pHidD_GetHidGuid;
@ -27,6 +29,8 @@ _HidD_GetAttributes pHidD_GetAttributes;
_HidD_GetPreparsedData pHidD_GetPreparsedData;
_HidP_GetCaps pHidP_GetCaps;
_HidD_FreePreparsedData pHidD_FreePreparsedData;
_HidD_GetFeature pHidD_GetFeature;
_HidD_SetFeature pHidD_SetFeature;
HMODULE hModHid = 0;
@ -40,7 +44,9 @@ int InitHid() {
(pHidD_GetAttributes = (_HidD_GetAttributes) GetProcAddress(hModHid, "HidD_GetAttributes")) &&
(pHidD_GetPreparsedData = (_HidD_GetPreparsedData) GetProcAddress(hModHid, "HidD_GetPreparsedData")) &&
(pHidP_GetCaps = (_HidP_GetCaps) GetProcAddress(hModHid, "HidP_GetCaps")) &&
(pHidD_FreePreparsedData = (_HidD_FreePreparsedData) GetProcAddress(hModHid, "HidD_FreePreparsedData"))) {
(pHidD_FreePreparsedData = (_HidD_FreePreparsedData) GetProcAddress(hModHid, "HidD_FreePreparsedData")) &&
(pHidD_GetFeature = (_HidD_GetFeature) GetProcAddress(hModHid, "HidD_GetFeature")) &&
(pHidD_SetFeature = (_HidD_SetFeature) GetProcAddress(hModHid, "HidD_SetFeature"))) {
pHidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
return 1;
}
@ -82,7 +88,7 @@ int FindHids(HidDeviceInfo **foundDevs, int vid, int pid) {
if (pHidD_GetPreparsedData(hfile, &pData)) {
if (HIDP_STATUS_SUCCESS == pHidP_GetCaps(pData, &caps)) {
if (numFoundDevs % 32 == 0) {
*foundDevs = (HidDeviceInfo*) realloc(foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs));
*foundDevs = (HidDeviceInfo*) realloc(*foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs));
}
HidDeviceInfo *dev = &foundDevs[0][numFoundDevs++];
dev->caps = caps;

View File

@ -35,5 +35,6 @@ struct HidDeviceInfo {
};
void UninitHid();
int FindHids(HidDeviceInfo **foundDevs, int vid, int pid);
#endif

View File

@ -97,12 +97,13 @@ enum DeviceAPI {
WM = 2,
RAW = 3,
XINPUT = 4,
DS3 = 5,
// Not currently used.
LLHOOK = 5,
LLHOOK = 6,
// Not a real API, obviously. Only used with keyboards,
// to ignore individual buttons. Wrapper itself takes care
// of ignoring bound keys. Otherwise, works normally.
IGNORE_KEYBOARD = 6,
IGNORE_KEYBOARD = 7,
};
enum DeviceType {

View File

@ -17,6 +17,8 @@
#include "KeyboardQueue.h"
#include "svnrev.h"
#include "resource.h"
#include "DualShock3.h"
#include "HidDevice.h"
#ifdef PCSX2_DEBUG
#include "crtdbg.h"
@ -260,6 +262,8 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, void* lpvReserved) {
while (openCount)
PADclose();
PADshutdown();
UninitHid();
UninitLibUsb();
}
return 1;
}
@ -969,20 +973,20 @@ u8 CALLBACK PADpoll(u8 value) {
u8 b1 = 0xFF, b2 = 0xFF;
for (i = 0; i<4; i++) {
b1 -= (sum->buttons[i]>=0xF0) << i;
b1 -= (sum->buttons[i]>=0x30) << i;
}
for (i = 0; i<8; i++) {
b2 -= (sum->buttons[i+4]>=0xF0) << i;
b2 -= (sum->buttons[i+4]>=0x30) << i;
}
if (config.padConfigs[query.port][query.slot].type == GuitarPad && !config.GH2) {
sum->sticks[0].horiz = -255;
// Not sure about this. Forces wammy to be from 0 to 0x7F.
// if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0;
}
b1 -= ((sum->sticks[0].vert<=-0xF0) << 4);
b1 -= ((sum->sticks[0].horiz>=0xF0) << 5);
b1 -= ((sum->sticks[0].vert>=0xF0) << 6);
b1 -= ((sum->sticks[0].horiz<=-0xF0) << 7);
b1 -= ((sum->sticks[0].vert<=-0x30) << 4);
b1 -= ((sum->sticks[0].horiz>=0x30) << 5);
b1 -= ((sum->sticks[0].vert>=0x30) << 6);
b1 -= ((sum->sticks[0].horiz<=-0x30) << 7);
query.response[3] = b1;
query.response[4] = b2;

View File

@ -27,18 +27,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// TEXTINCLUDE
//
1 TEXTINCLUDE
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
2 TEXTINCLUDE
BEGIN
"#include <winres.h>\r\n"
"\0"
END
3 TEXTINCLUDE
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
@ -198,21 +198,22 @@ BEGIN
PUSHBUTTON "Small Motor",ID_SMALL_MOTOR,347,291,64,14
END
IDD_GENERAL DIALOGEX 0, 0, 424, 318
IDD_GENERAL DIALOGEX 0, 0, 424, 327
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
GROUPBOX "Input APIs",IDC_STATIC,7,6,410,131
GROUPBOX "Input APIs",IDC_STATIC,7,6,410,141
GROUPBOX "Keyboard API",IDC_STATIC,16,16,192,61
CONTROL "Windows messaging (Recommended)",IDC_KB_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,22,28,134,10
CONTROL "Raw input (XP and later only)",IDC_KB_RAW,"Button",BS_AUTORADIOBUTTON,22,40,112,10
CONTROL "DirectInput",IDC_KB_DI,"Button",BS_AUTORADIOBUTTON,22,52,112,10
CONTROL "Disable (Intended for use with other pad plugins)",IDC_KB_DISABLE,
"Button",BS_AUTORADIOBUTTON,22,64,175,10
GROUPBOX "Game Device APIs",IDC_STATIC,16,81,191,49
CONTROL "DirectInput",IDC_G_DI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,92,65,10
CONTROL "XInput (Xbox 360 controllers only)",IDC_G_XI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,104,125,10
CONTROL "Monitor when in background",IDC_BACKGROUND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,116,106,10
GROUPBOX "Game Device APIs",IDC_STATIC,16,79,191,61
CONTROL "DirectInput",IDC_G_DI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,91,65,10
CONTROL "XInput (Xbox 360 controllers only)",IDC_G_XI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,103,125,10
CONTROL "DualShock 3 (Requires libusb)",IDC_G_DS3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,115,110,10
CONTROL "Monitor when in background",IDC_BACKGROUND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,127,106,10
GROUPBOX "Mouse API",IDC_STATIC,216,16,192,85
CONTROL "Windows messaging (Recommended)",IDC_M_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,223,27,134,10
CONTROL "Raw input (XP and later only)",IDC_M_RAW,"Button",BS_AUTORADIOBUTTON,223,39,112,10
@ -220,34 +221,34 @@ BEGIN
CONTROL "Disable",IDC_M_DISABLE,"Button",BS_AUTORADIOBUTTON,223,63,39,10
CONTROL "Start without mouse focus",IDC_MOUSE_UNFOCUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,75,97,10
CONTROL "Always hide cursor",IDC_FORCE_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,87,71,10
GROUPBOX "Advanced",IDC_STATIC,216,105,192,25
GROUPBOX "Advanced",IDC_STATIC,216,111,192,28
CONTROL "Allow binding multiple PS2 controls to one PC control",IDC_MULTIPLE_BINDING,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,116,182,10
GROUPBOX "Pads",IDC_STATIC,7,140,410,67
CONTROL "Port 1 Multitap",IDC_MULTITAP1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,152,63,10
CONTROL "Port 2 Multitap",IDC_MULTITAP2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,164,63,10
CONTROL "",IDC_PAD_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_TABSTOP,81,151,183,50,WS_EX_CLIENTEDGE
COMBOBOX IDC_PAD_TYPE,270,152,140,41,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,124,182,10
GROUPBOX "Pads",IDC_STATIC,7,150,410,67
CONTROL "Port 1 Multitap",IDC_MULTITAP1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,162,63,10
CONTROL "Port 2 Multitap",IDC_MULTITAP2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,174,63,10
CONTROL "",IDC_PAD_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_TABSTOP,81,161,183,50,WS_EX_CLIENTEDGE
COMBOBOX IDC_PAD_TYPE,270,162,140,41,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Use analog mode whenever possible",IDC_ANALOG_START1,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,169,132,10
GROUPBOX "Device Diagnostics",IDC_STATIC,7,211,201,99
CONTROL "",IDC_LIST,"SysListView32",LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,15,224,185,61,WS_EX_CLIENTEDGE
PUSHBUTTON "Test Device",ID_TEST,86,289,57,15
PUSHBUTTON "Refresh",ID_REFRESH,152,289,48,15
GROUPBOX "Miscellaneous",IDC_STATIC,216,211,201,34
CONTROL "Use GS thread",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,221,62,10
CONTROL "Disable screensaver",IDC_DISABLE_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,232,80,10
CONTROL "Local volume control",IDC_VISTA_VOLUME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,221,77,10
CONTROL "Enable logging",IDC_DEBUG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,232,62,10
GROUPBOX "Hacks",IDC_STATIC,216,247,201,45
CONTROL "Send escape on window close",IDC_CLOSE_HACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,257,113,10
CONTROL "Exit emulator on window close",IDC_CLOSE_HACK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,268,112,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,179,132,10
GROUPBOX "Device Diagnostics",IDC_STATIC,7,221,201,99
CONTROL "",IDC_LIST,"SysListView32",LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,15,234,185,61,WS_EX_CLIENTEDGE
PUSHBUTTON "Test Device",ID_TEST,86,299,57,15
PUSHBUTTON "Refresh",ID_REFRESH,152,299,48,15
GROUPBOX "Miscellaneous",IDC_STATIC,216,221,201,34
CONTROL "Use GS thread",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,231,62,10
CONTROL "Disable screensaver",IDC_DISABLE_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,242,80,10
CONTROL "Local volume control",IDC_VISTA_VOLUME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,231,77,10
CONTROL "Enable logging",IDC_DEBUG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,242,62,10
GROUPBOX "Hacks",IDC_STATIC,216,257,201,45
CONTROL "Send escape on window close",IDC_CLOSE_HACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,267,113,10
CONTROL "Exit emulator on window close",IDC_CLOSE_HACK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,278,112,10
CONTROL "Safe fullscreen exit on escape",IDC_ESCAPE_FULLSCREEN_HACK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,279,112,10
CONTROL "Save state # in title",IDC_SAVE_STATE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,257,79,10
CONTROL "Guitar Hero 2 Hack",IDC_GH2_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,268,76,10
PUSHBUTTON "Load Bindings",ID_LOAD,283,295,62,15
PUSHBUTTON "Save Bindings",ID_SAVE,355,295,62,15
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,289,112,10
CONTROL "Save state # in title",IDC_SAVE_STATE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,267,79,10
CONTROL "Guitar Hero 2 Hack",IDC_GH2_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,278,76,10
PUSHBUTTON "Load Bindings",ID_LOAD,283,305,62,15
PUSHBUTTON "Save Bindings",ID_SAVE,355,305,62,15
END
IDD_ABOUT DIALOGEX 0, 0, 108, 66
@ -275,7 +276,7 @@ END
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
GUIDELINES DESIGNINFO
BEGIN
IDD_CONFIG, DIALOG
BEGIN
@ -298,7 +299,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 417
TOPMARGIN, 7
BOTTOMMARGIN, 310
BOTTOMMARGIN, 319
END
IDD_ABOUT, DIALOG

View File

@ -608,6 +608,14 @@
RelativePath=".\DirectInput.h"
>
</File>
<File
RelativePath=".\DualShock3.cpp"
>
</File>
<File
RelativePath=".\DualShock3.h"
>
</File>
<File
RelativePath=".\HidDevice.cpp"
>
@ -640,6 +648,10 @@
RelativePath=".\RawInput.h"
>
</File>
<File
RelativePath=".\usb.h"
>
</File>
<File
RelativePath=".\WindowsKeyboard.cpp"
>

View File

@ -543,6 +543,14 @@
RelativePath=".\DirectInput.h"
>
</File>
<File
RelativePath=".\DualShock3.cpp"
>
</File>
<File
RelativePath=".\DualShock3.h"
>
</File>
<File
RelativePath=".\HidDevice.cpp"
>
@ -575,6 +583,10 @@
RelativePath=".\RawInput.h"
>
</File>
<File
RelativePath=".\usb.h"
>
</File>
<File
RelativePath=".\WindowsKeyboard.cpp"
>

View File

@ -1,9 +1,7 @@
#include "Global.h"
#include "VKey.h"
#include "DirectInput.h"
#include <xinput.h>
#include "InputManager.h"
#include "DeviceEnumerator.h"
// This way, I don't require that XInput junk be installed.
typedef void (CALLBACK *_XInputEnable)(BOOL enable);

View File

@ -1,3 +1 @@
#include "InputManager.h"
void EnumXInputDevices();

View File

@ -23,7 +23,8 @@
#define IDC_M_RAW 1109
#define IDC_G_XI 1110
#define IDC_G_DI 1111
#define IDC_CLOSE_HACK2 1112
#define IDC_G_DS3 1112
#define IDC_CLOSE_HACK2 1113
#define IDC_DEBUG_FILE 1114
#define IDC_GUITAR1 1115
#define IDC_ANALOG_START1 1117
@ -137,7 +138,7 @@
#define IDC_FF_AXIS8_SCALE 0x1383
// Next default values for new objects
//
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 112

397
plugins/LilyPad/usb.h Normal file
View File

@ -0,0 +1,397 @@
// Note: From libusb.
#ifndef __USB_H__
#define __USB_H__
#include <stdlib.h>
#include <windows.h>
/*
* 'interface' is defined somewhere in the Windows header files. This macro
* is deleted here to avoid conflicts and compile errors.
*/
#ifdef interface
#undef interface
#endif
/*
* PATH_MAX from limits.h can't be used on Windows if the dll and
* import libraries are build/used by different compilers
*/
#define LIBUSB_PATH_MAX 512
/*
* USB spec information
*
* This is all stuff grabbed from various USB specs and is pretty much
* not subject to change
*/
/*
* Device and/or Interface Class codes
*/
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
#define USB_CLASS_AUDIO 1
#define USB_CLASS_COMM 2
#define USB_CLASS_HID 3
#define USB_CLASS_PRINTER 7
#define USB_CLASS_MASS_STORAGE 8
#define USB_CLASS_HUB 9
#define USB_CLASS_DATA 10
#define USB_CLASS_VENDOR_SPEC 0xff
/*
* Descriptor types
*/
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
#define USB_DT_STRING 0x03
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
#define USB_DT_HID 0x21
#define USB_DT_REPORT 0x22
#define USB_DT_PHYSICAL 0x23
#define USB_DT_HUB 0x29
/*
* Descriptor sizes per descriptor type
*/
#define USB_DT_DEVICE_SIZE 18
#define USB_DT_CONFIG_SIZE 9
#define USB_DT_INTERFACE_SIZE 9
#define USB_DT_ENDPOINT_SIZE 7
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
#define USB_DT_HUB_NONVAR_SIZE 7
/* ensure byte-packed structures */
#include <pshpack1.h>
/* All standard descriptors have these 2 fields in common */
struct usb_descriptor_header {
unsigned char bLength;
unsigned char bDescriptorType;
};
/* String descriptor */
struct usb_string_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short wData[1];
};
/* HID descriptor */
struct usb_hid_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short bcdHID;
unsigned char bCountryCode;
unsigned char bNumDescriptors;
};
/* Endpoint descriptor */
#define USB_MAXENDPOINTS 32
struct usb_endpoint_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned char bEndpointAddress;
unsigned char bmAttributes;
unsigned short wMaxPacketSize;
unsigned char bInterval;
unsigned char bRefresh;
unsigned char bSynchAddress;
unsigned char *extra; /* Extra descriptors */
int extralen;
};
#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */
#define USB_ENDPOINT_DIR_MASK 0x80
#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */
#define USB_ENDPOINT_TYPE_CONTROL 0
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1
#define USB_ENDPOINT_TYPE_BULK 2
#define USB_ENDPOINT_TYPE_INTERRUPT 3
/* Interface descriptor */
#define USB_MAXINTERFACES 32
struct usb_interface_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned char bInterfaceNumber;
unsigned char bAlternateSetting;
unsigned char bNumEndpoints;
unsigned char bInterfaceClass;
unsigned char bInterfaceSubClass;
unsigned char bInterfaceProtocol;
unsigned char iInterface;
struct usb_endpoint_descriptor *endpoint;
unsigned char *extra; /* Extra descriptors */
int extralen;
};
#define USB_MAXALTSETTING 128 /* Hard limit */
struct usb_interface {
struct usb_interface_descriptor *altsetting;
int num_altsetting;
};
/* Configuration descriptor information.. */
#define USB_MAXCONFIG 8
struct usb_config_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short wTotalLength;
unsigned char bNumInterfaces;
unsigned char bConfigurationValue;
unsigned char iConfiguration;
unsigned char bmAttributes;
unsigned char MaxPower;
struct usb_interface *interface;
unsigned char *extra; /* Extra descriptors */
int extralen;
};
/* Device descriptor */
struct usb_device_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short bcdUSB;
unsigned char bDeviceClass;
unsigned char bDeviceSubClass;
unsigned char bDeviceProtocol;
unsigned char bMaxPacketSize0;
unsigned short idVendor;
unsigned short idProduct;
unsigned short bcdDevice;
unsigned char iManufacturer;
unsigned char iProduct;
unsigned char iSerialNumber;
unsigned char bNumConfigurations;
};
struct usb_ctrl_setup {
unsigned char bRequestType;
unsigned char bRequest;
unsigned short wValue;
unsigned short wIndex;
unsigned short wLength;
};
/*
* Standard requests
*/
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
/* 0x02 is reserved */
#define USB_REQ_SET_FEATURE 0x03
/* 0x04 is reserved */
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_TYPE_STANDARD (0x00 << 5)
#define USB_TYPE_CLASS (0x01 << 5)
#define USB_TYPE_VENDOR (0x02 << 5)
#define USB_TYPE_RESERVED (0x03 << 5)
#define USB_RECIP_DEVICE 0x00
#define USB_RECIP_INTERFACE 0x01
#define USB_RECIP_ENDPOINT 0x02
#define USB_RECIP_OTHER 0x03
/*
* Various libusb API related stuff
*/
#define USB_ENDPOINT_IN 0x80
#define USB_ENDPOINT_OUT 0x00
/* Error codes */
#define USB_ERROR_BEGIN 500000
/*
* This is supposed to look weird. This file is generated from autoconf
* and I didn't want to make this too complicated.
*/
#define USB_LE16_TO_CPU(x)
/* Data types */
/* struct usb_device; */
/* struct usb_bus; */
struct usb_device {
struct usb_device *next, *prev;
char filename[LIBUSB_PATH_MAX];
struct usb_bus *bus;
struct usb_device_descriptor descriptor;
struct usb_config_descriptor *config;
void *dev; /* Darwin support */
unsigned char devnum;
unsigned char num_children;
struct usb_device **children;
};
struct usb_bus {
struct usb_bus *next, *prev;
char dirname[LIBUSB_PATH_MAX];
struct usb_device *devices;
unsigned long location;
struct usb_device *root_dev;
};
/* Version information, Windows specific */
struct usb_version {
struct {
int major;
int minor;
int micro;
int nano;
} dll;
struct {
int major;
int minor;
int micro;
int nano;
} driver;
};
struct usb_dev_handle;
typedef struct usb_dev_handle usb_dev_handle;
/* Variables */
#ifndef __USB_C__
#define usb_busses usb_get_busses()
#endif
#include <poppack.h>
#ifdef GOAT
#ifdef __cplusplus
extern "C" {
#endif
/* Function prototypes */
/* usb.c */
usb_dev_handle *usb_open(struct usb_device *dev);
int usb_close(usb_dev_handle *dev);
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
size_t buflen);
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
size_t buflen);
/* descriptors.c */
int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
unsigned char type, unsigned char index,
void *buf, int size);
int usb_get_descriptor(usb_dev_handle *udev, unsigned char type,
unsigned char index, void *buf, int size);
/* <arch>.c */
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
int timeout);
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
int timeout);
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
int timeout);
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
int timeout);
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
int value, int index, char *bytes, int size,
int timeout);
int usb_set_configuration(usb_dev_handle *dev, int configuration);
int usb_claim_interface(usb_dev_handle *dev, int interface);
int usb_release_interface(usb_dev_handle *dev, int interface);
int usb_set_altinterface(usb_dev_handle *dev, int alternate);
int usb_resetep(usb_dev_handle *dev, unsigned int ep);
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
int usb_reset(usb_dev_handle *dev);
char *usb_strerror(void);
void usb_init(void);
void usb_set_debug(int level);
int usb_find_busses(void);
int usb_find_devices(void);
struct usb_device *usb_device(usb_dev_handle *dev);
struct usb_bus *usb_get_busses(void);
/* Windows specific functions */
#define LIBUSB_HAS_INSTALL_SERVICE_NP 1
int usb_install_service_np(void);
void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance,
LPSTR cmd_line, int cmd_show);
#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1
int usb_uninstall_service_np(void);
void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance,
LPSTR cmd_line, int cmd_show);
#define LIBUSB_HAS_INSTALL_DRIVER_NP 1
int usb_install_driver_np(const char *inf_file);
void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance,
LPSTR cmd_line, int cmd_show);
#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1
int usb_touch_inf_file_np(const char *inf_file);
void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance,
LPSTR cmd_line, int cmd_show);
#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1
int usb_install_needs_restart_np(void);
const struct usb_version *usb_get_version(void);
int usb_isochronous_setup_async(usb_dev_handle *dev, void **context,
unsigned char ep, int pktsize);
int usb_bulk_setup_async(usb_dev_handle *dev, void **context,
unsigned char ep);
int usb_interrupt_setup_async(usb_dev_handle *dev, void **context,
unsigned char ep);
int usb_submit_async(void *context, char *bytes, int size);
int usb_reap_async(void *context, int timeout);
int usb_reap_async_nocancel(void *context, int timeout);
int usb_cancel_async(void *context);
int usb_free_async(void **context);
#ifdef __cplusplus
}
#endif
#endif
#endif /* __USB_H__ */