mirror of https://github.com/PCSX2/pcsx2.git
LilyPad: A number of small fixups.
DirectInput devices corresponding XInput devices should be listed as "[Detached]" when XInput is enabled. No idea if this works, as it requires an XBox 360 controller to fully test. FF Axes now sorted, rather than being displayed in the order MS returns them. Small motor DirectInput binding now correctly displays "Square" effect type in list when first created. Attempt to more accurately model "soft" vs "hard" presses. Don't have a game where this matters, so no idea if it works. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1607 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
5025b3886e
commit
3cbd298cff
|
@ -130,7 +130,11 @@ void SetLogSliderVal(HWND hWnd, int id, HWND hWndText, int val) {
|
|||
|
||||
void RefreshEnabledDevices(int updateDeviceList) {
|
||||
// Clears all device state.
|
||||
if (updateDeviceList) EnumDevices();
|
||||
static int lastXInputState = -1;
|
||||
if (updateDeviceList || lastXInputState != config.gameApis.xInput) {
|
||||
EnumDevices(config.gameApis.xInput);
|
||||
lastXInputState = config.gameApis.xInput;
|
||||
}
|
||||
|
||||
for (int i=0; i<dm->numDevices; i++) {
|
||||
Device *dev = dm->devices[i];
|
||||
|
@ -1094,11 +1098,16 @@ int CreateEffectBinding(Device *dev, wchar_t *effectID, unsigned int port, unsig
|
|||
if (port > 1 || slot>3 || motor > 1 || !dev->numFFEffectTypes) {
|
||||
return -1;
|
||||
}
|
||||
if (!effectID) {
|
||||
effectID = dev->ffEffectTypes[0].effectID;
|
||||
ForceFeedbackEffectType *eff = 0;
|
||||
if (effectID) {
|
||||
eff = dev->GetForcefeedbackEffect(effectID);
|
||||
}
|
||||
if (!eff) {
|
||||
eff = dev->ffEffectTypes;
|
||||
}
|
||||
if (!eff) {
|
||||
return -1;
|
||||
}
|
||||
ForceFeedbackEffectType *eff = dev->GetForcefeedbackEffect(effectID);
|
||||
if (!eff) return -1;
|
||||
int effectIndex = eff - dev->ffEffectTypes;
|
||||
dev->pads[port][slot].ffBindings = (ForceFeedbackBinding*) realloc(dev->pads[port][slot].ffBindings, (dev->pads[port][slot].numFFBindings+1) * sizeof(ForceFeedbackBinding));
|
||||
int newIndex = dev->pads[port][slot].numFFBindings;
|
||||
|
@ -1404,7 +1413,14 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
|
|||
if (index < (unsigned int) dm->numDevices) {
|
||||
Device *dev = dm->devices[index];
|
||||
ForceFeedbackBinding *b;
|
||||
int count = CreateEffectBinding(dev, 0, port, slot, cmd-ID_BIG_MOTOR, &b);
|
||||
wchar_t *effectID = 0;
|
||||
if (dev->api == DI) {
|
||||
// Constant effect.
|
||||
if (cmd == ID_BIG_MOTOR) effectID = L"13541C20-8E33-11D0-9AD0-00A0C9A06E35";
|
||||
// Square.
|
||||
else effectID = L"13541C22-8E33-11D0-9AD0-00A0C9A06E35";
|
||||
}
|
||||
int count = CreateEffectBinding(dev, effectID, port, slot, cmd-ID_BIG_MOTOR, &b);
|
||||
if (b) {
|
||||
int needSet = 1;
|
||||
if (dev->api == XINPUT && dev->numFFAxes == 2) {
|
||||
|
@ -1418,7 +1434,6 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
|
|||
}
|
||||
else if (dev->api == DI) {
|
||||
int bigIndex=0, littleIndex=0;
|
||||
int constantEffect = 0, squareEffect = 0;
|
||||
int j;
|
||||
for (j=0; j<dev->numFFAxes; j++) {
|
||||
// DI object instance. 0 is x-axis, 1 is y-axis.
|
||||
|
@ -1430,20 +1445,14 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
|
|||
littleIndex = j;
|
||||
}
|
||||
}
|
||||
for (j=0; j<dev->numFFEffectTypes; j++) {
|
||||
if (!wcsicmp(L"13541C20-8E33-11D0-9AD0-00A0C9A06E35", dev->ffEffectTypes[j].effectID)) constantEffect = j;
|
||||
if (!wcsicmp(L"13541C22-8E33-11D0-9AD0-00A0C9A06E35", dev->ffEffectTypes[j].effectID)) squareEffect = j;
|
||||
}
|
||||
needSet = 0;
|
||||
if (cmd == ID_BIG_MOTOR) {
|
||||
b->axes[bigIndex].force = BASE_SENSITIVITY;
|
||||
b->axes[littleIndex].force = 1;
|
||||
b->effectIndex = constantEffect;
|
||||
}
|
||||
else {
|
||||
b->axes[bigIndex].force = 1;
|
||||
b->axes[littleIndex].force = BASE_SENSITIVITY;
|
||||
b->effectIndex = squareEffect;
|
||||
}
|
||||
}
|
||||
if (needSet) {
|
||||
|
@ -1695,7 +1704,7 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L
|
|||
selected = 0;
|
||||
ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER, LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER);
|
||||
SendMessage(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
|
||||
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) L"Disabled");
|
||||
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) L"Unplugged");
|
||||
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) L"Dualshock 2");
|
||||
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) L"Guitar");
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "RawInput.h"
|
||||
#include "XInput.h"
|
||||
|
||||
void EnumDevices() {
|
||||
void EnumDevices(int hideDXXinput) {
|
||||
// Needed for enumeration of some device types.
|
||||
dm->ReleaseInput();
|
||||
InputDeviceManager *oldDm = dm;
|
||||
|
@ -17,7 +17,7 @@ void EnumDevices() {
|
|||
EnumWindowsMessagingDevices();
|
||||
EnumRawInputDevices();
|
||||
EnumXInputDevices();
|
||||
EnumDirectInputDevices();
|
||||
EnumDirectInputDevices(hideDXXinput);
|
||||
|
||||
dm->CopyBindings(oldDm->numDevices, oldDm->devices);
|
||||
|
||||
|
|
|
@ -9,5 +9,5 @@ struct InitInfo {
|
|||
HWND hWndButton;
|
||||
};
|
||||
|
||||
void EnumDevices();
|
||||
void EnumDevices(int hideDXXinput);
|
||||
|
||||
|
|
|
@ -9,6 +9,16 @@
|
|||
#include "PS2Etypes.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// All for getting GUIDs of XInput devices....
|
||||
#include <wbemidl.h>
|
||||
#include <oleauto.h>
|
||||
// MS's code imports wmsstd.h, thus requiring the entire windows
|
||||
// media SDK also be installed for a simple macro. This is
|
||||
// simpler and less silly.
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
// Aka htons, without the winsock dependency.
|
||||
inline static u16 flipShort(u16 s) {
|
||||
return (s>>8) | (s<<8);
|
||||
|
@ -440,10 +450,126 @@ BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOI
|
|||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
// Evil code from MS's site. If only they'd just made a way to get
|
||||
// an XInput device's GUID directly in the first place...
|
||||
BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput )
|
||||
{
|
||||
IWbemLocator* pIWbemLocator = NULL;
|
||||
IEnumWbemClassObject* pEnumDevices = NULL;
|
||||
IWbemClassObject* pDevices[20] = {0};
|
||||
IWbemServices* pIWbemServices = NULL;
|
||||
BSTR bstrNamespace = NULL;
|
||||
BSTR bstrDeviceID = NULL;
|
||||
BSTR bstrClassName = NULL;
|
||||
DWORD uReturned = 0;
|
||||
bool bIsXinputDevice= false;
|
||||
UINT iDevice = 0;
|
||||
VARIANT var;
|
||||
HRESULT hr;
|
||||
|
||||
// CoInit if needed
|
||||
hr = CoInitialize(NULL);
|
||||
bool bCleanupCOM = SUCCEEDED(hr);
|
||||
|
||||
// Create WMI
|
||||
hr = CoCreateInstance( __uuidof(WbemLocator),
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IWbemLocator),
|
||||
(LPVOID*) &pIWbemLocator);
|
||||
if( FAILED(hr) || pIWbemLocator == NULL )
|
||||
goto LCleanup;
|
||||
|
||||
bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup;
|
||||
bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup;
|
||||
bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup;
|
||||
|
||||
// Connect to WMI
|
||||
hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L,
|
||||
0L, NULL, NULL, &pIWbemServices );
|
||||
if( FAILED(hr) || pIWbemServices == NULL )
|
||||
goto LCleanup;
|
||||
|
||||
// Switch security level to IMPERSONATE.
|
||||
CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
|
||||
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
|
||||
|
||||
hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices );
|
||||
if( FAILED(hr) || pEnumDevices == NULL )
|
||||
goto LCleanup;
|
||||
|
||||
// Loop over all devices
|
||||
for( ;; )
|
||||
{
|
||||
// Get 20 at a time
|
||||
hr = pEnumDevices->Next( 10000, 20, pDevices, &uReturned );
|
||||
if( FAILED(hr) )
|
||||
goto LCleanup;
|
||||
if( uReturned == 0 )
|
||||
break;
|
||||
|
||||
for( iDevice=0; iDevice<uReturned; iDevice++ )
|
||||
{
|
||||
// For each device, get its device ID
|
||||
hr = pDevices[iDevice]->Get( bstrDeviceID, 0L, &var, NULL, NULL );
|
||||
if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL )
|
||||
{
|
||||
// Check if the device ID contains "IG_". If it does, then it's an XInput device
|
||||
// This information can not be found from DirectInput
|
||||
if( wcsstr( var.bstrVal, L"IG_" ) )
|
||||
{
|
||||
// If it does, then get the VID/PID from var.bstrVal
|
||||
DWORD dwPid = 0, dwVid = 0;
|
||||
WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" );
|
||||
if( strVid && swscanf( strVid, L"VID_%4X", &dwVid ) != 1 )
|
||||
dwVid = 0;
|
||||
WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" );
|
||||
if( strPid && swscanf( strPid, L"PID_%4X", &dwPid ) != 1 )
|
||||
dwPid = 0;
|
||||
|
||||
// Compare the VID/PID to the DInput device
|
||||
DWORD dwVidPid = MAKELONG( dwVid, dwPid );
|
||||
if( dwVidPid == pGuidProductFromDirectInput->Data1 )
|
||||
{
|
||||
bIsXinputDevice = true;
|
||||
goto LCleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
SAFE_RELEASE( pDevices[iDevice] );
|
||||
}
|
||||
}
|
||||
|
||||
LCleanup:
|
||||
if(bstrNamespace)
|
||||
SysFreeString(bstrNamespace);
|
||||
if(bstrDeviceID)
|
||||
SysFreeString(bstrDeviceID);
|
||||
if(bstrClassName)
|
||||
SysFreeString(bstrClassName);
|
||||
for( iDevice=0; iDevice<20; iDevice++ )
|
||||
SAFE_RELEASE( pDevices[iDevice] );
|
||||
SAFE_RELEASE( pEnumDevices );
|
||||
SAFE_RELEASE( pIWbemLocator );
|
||||
SAFE_RELEASE( pIWbemServices );
|
||||
|
||||
if( bCleanupCOM )
|
||||
CoUninitialize();
|
||||
|
||||
return bIsXinputDevice;
|
||||
}
|
||||
|
||||
|
||||
struct DeviceEnumInfo {
|
||||
IDirectInput8 *di8;
|
||||
int ignoreXInput;
|
||||
};
|
||||
|
||||
BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
|
||||
IDirectInput8* di8 = (IDirectInput8*)pvRef;
|
||||
IDirectInput8* di8 = ((DeviceEnumInfo*)pvRef)->di8;
|
||||
const wchar_t *name;
|
||||
wchar_t temp[40];
|
||||
//if (((DeviceEnumInfo*)pvRef)->ignoreXInput && lpddi->
|
||||
if (lpddi->tszInstanceName[0]) {
|
||||
name = lpddi->tszInstanceName;
|
||||
}
|
||||
|
@ -476,11 +602,13 @@ BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
|
|||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
void EnumDirectInputDevices() {
|
||||
IDirectInput8* di8 = GetDirectInput();
|
||||
if (!di8) return;
|
||||
void EnumDirectInputDevices(int ignoreXInput) {
|
||||
DeviceEnumInfo enumInfo;
|
||||
enumInfo.di8 = GetDirectInput();
|
||||
if (!enumInfo.di8) return;
|
||||
enumInfo.ignoreXInput = ignoreXInput;
|
||||
di8d.deviceCount = 0;
|
||||
di8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, di8, DIEDFL_ATTACHEDONLY);
|
||||
enumInfo.di8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, &enumInfo, DIEDFL_ATTACHEDONLY);
|
||||
ReleaseDirectInput();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#include "InputManager.h"
|
||||
|
||||
void EnumDirectInputDevices();
|
||||
void EnumDirectInputDevices(int ignoreXInput);
|
||||
|
|
|
@ -112,15 +112,27 @@ void Device::AddFFAxis(const wchar_t *displayName, int id) {
|
|||
ffAxes[numFFAxes].id = id;
|
||||
ffAxes[numFFAxes].displayName = wcsdup(displayName);
|
||||
numFFAxes++;
|
||||
int bindingsExist = 0;
|
||||
for (int port=0; port<2; port++) {
|
||||
for (int slot=0; slot<4; slot++) {
|
||||
for (int i=0; i<pads[port][slot].numFFBindings; i++) {
|
||||
ForceFeedbackBinding *b = pads[port][slot].ffBindings+i;
|
||||
b->axes = (AxisEffectInfo*) realloc(b->axes, sizeof(AxisEffectInfo) * (numFFAxes));
|
||||
memset(b->axes + (numFFAxes-1), 0, sizeof(AxisEffectInfo));
|
||||
bindingsExist = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Generally the case when not loading a binding file.
|
||||
if (!bindingsExist) {
|
||||
int i = numFFAxes-1;
|
||||
ForceFeedbackAxis temp = ffAxes[i];
|
||||
while (i && temp.id < ffAxes[i-1].id) {
|
||||
ffAxes[i] = ffAxes[i-1];
|
||||
i--;
|
||||
}
|
||||
ffAxes[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void Device::AllocState() {
|
||||
|
|
|
@ -969,20 +969,20 @@ u8 CALLBACK PADpoll(u8 value) {
|
|||
|
||||
u8 b1 = 0xFF, b2 = 0xFF;
|
||||
for (i = 0; i<4; i++) {
|
||||
b1 -= (sum->buttons[i]>=128) << i;
|
||||
b1 -= (sum->buttons[i]>=0xF0) << i;
|
||||
}
|
||||
for (i = 0; i<8; i++) {
|
||||
b2 -= (sum->buttons[i+4]>=128) << i;
|
||||
b2 -= (sum->buttons[i+4]>=0xF0) << 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<=-128) << 4);
|
||||
b1 -= ((sum->sticks[0].horiz>=128) << 5);
|
||||
b1 -= ((sum->sticks[0].vert>=128) << 6);
|
||||
b1 -= ((sum->sticks[0].horiz<=-128) << 7);
|
||||
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);
|
||||
query.response[3] = b1;
|
||||
query.response[4] = b2;
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ BEGIN
|
|||
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 | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_PAD_TYPE,270,152,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
|
||||
|
|
Loading…
Reference in New Issue