mirror of https://github.com/PCSX2/pcsx2.git
LilyPad: Version number updated in rc copy. Refresh device list bug on device insertion/removal fixed. Attempt to resolve potential XInput/DirectInput infighting by deleting DirectInput interfaces to disabled/bindingless DirectInput devices.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@565 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
a22035664d
commit
6ecd052079
|
@ -25,6 +25,31 @@ static void GUIDtoString(wchar_t *data, const GUID *pg) {
|
||||||
flipLong(((u32*)pg->Data4)[1]));
|
flipLong(((u32*)pg->Data4)[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DirectInput8Data {
|
||||||
|
IDirectInput8* lpDI8;
|
||||||
|
int refCount;
|
||||||
|
int deviceCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
DirectInput8Data di8d = {0,0,0};
|
||||||
|
|
||||||
|
IDirectInput8* GetDirectInput() {
|
||||||
|
if (!di8d.lpDI8) {
|
||||||
|
if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void**) &di8d.lpDI8, 0))) return 0;
|
||||||
|
}
|
||||||
|
di8d.refCount++;
|
||||||
|
return di8d.lpDI8;
|
||||||
|
}
|
||||||
|
void ReleaseDirectInput() {
|
||||||
|
if (di8d.refCount) {
|
||||||
|
di8d.refCount--;
|
||||||
|
if (!di8d.refCount) {
|
||||||
|
di8d.lpDI8->Release();
|
||||||
|
di8d.lpDI8 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int StringToGUID(GUID *pg, wchar_t *dataw) {
|
static int StringToGUID(GUID *pg, wchar_t *dataw) {
|
||||||
char data[100];
|
char data[100];
|
||||||
if (wcslen(dataw) > 50) return 0;
|
if (wcslen(dataw) > 50) return 0;
|
||||||
|
@ -59,54 +84,14 @@ public:
|
||||||
DI8Effect *diEffects;
|
DI8Effect *diEffects;
|
||||||
|
|
||||||
IDirectInputDevice8 *did;
|
IDirectInputDevice8 *did;
|
||||||
DirectInputDevice(DeviceType type, IDirectInputDevice8* did, wchar_t *displayName, wchar_t *instanceID, wchar_t *productID) : Device(DI, type, displayName, instanceID, productID) {
|
GUID guidInstance;
|
||||||
int i;
|
DirectInputDevice(DeviceType type, IDirectInputDevice8* did, wchar_t *displayName, wchar_t *instanceID, wchar_t *productID, GUID guid) : Device(DI, type, displayName, instanceID, productID) {
|
||||||
diEffects = 0;
|
diEffects = 0;
|
||||||
this->did = did;
|
guidInstance = guid;
|
||||||
|
this->did = 0;
|
||||||
did->EnumEffects(EnumEffectsCallback, this, DIEFT_ALL);
|
did->EnumEffects(EnumEffectsCallback, this, DIEFT_ALL);
|
||||||
did->EnumObjects(EnumDeviceObjectsCallback, this, DIDFT_ALL);
|
did->EnumObjects(EnumDeviceObjectsCallback, this, DIDFT_ALL);
|
||||||
DIOBJECTDATAFORMAT *formats = (DIOBJECTDATAFORMAT*)malloc(sizeof(DIOBJECTDATAFORMAT) * numPhysicalControls);
|
did->Release();
|
||||||
for (i=0; i<numPhysicalControls; i++) {
|
|
||||||
formats[i].pguid = 0;
|
|
||||||
formats[i].dwType = physicalControls[i].type | DIDFT_MAKEINSTANCE(physicalControls[i].id);
|
|
||||||
formats[i].dwOfs = 4*i;
|
|
||||||
formats[i].dwFlags = 0;
|
|
||||||
}
|
|
||||||
DIDATAFORMAT format;
|
|
||||||
format.dwSize = sizeof(format);
|
|
||||||
format.dwDataSize = 4 * numPhysicalControls;
|
|
||||||
format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
|
|
||||||
format.dwFlags = 0;
|
|
||||||
format.dwNumObjs = numPhysicalControls;
|
|
||||||
format.rgodf = formats;
|
|
||||||
int res = did->SetDataFormat(&format);
|
|
||||||
for (i=0; i<numPhysicalControls; i++) {
|
|
||||||
if (physicalControls[i].type == ABSAXIS) {
|
|
||||||
DIPROPRANGE prop;
|
|
||||||
prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
|
||||||
prop.diph.dwSize = sizeof(DIPROPRANGE);
|
|
||||||
prop.diph.dwObj = formats[i].dwType;
|
|
||||||
prop.diph.dwHow = DIPH_BYID;
|
|
||||||
prop.lMin = -FULLY_DOWN;
|
|
||||||
prop.lMax = FULLY_DOWN;
|
|
||||||
did->SetProperty(DIPROP_RANGE, &prop.diph);
|
|
||||||
|
|
||||||
// May do something like this again, if there's any need.
|
|
||||||
/*
|
|
||||||
if (FAILED(DI->did->SetProperty(DIPROP_RANGE, &prop.diph))) {
|
|
||||||
if (FAILED(DI->did->GetProperty(DIPROP_RANGE, &prop.diph))) {
|
|
||||||
// ????
|
|
||||||
DI->objects[i].min = prop.lMin;
|
|
||||||
DI->objects[i].max = prop.lMax;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DI->objects[i].min = prop.lMin;
|
|
||||||
DI->objects[i].max = prop.lMax;
|
|
||||||
//*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(formats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {
|
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {
|
||||||
|
@ -152,7 +137,59 @@ public:
|
||||||
|
|
||||||
int Activate(void *d) {
|
int Activate(void *d) {
|
||||||
int i, j;
|
int i, j;
|
||||||
|
IDirectInput8 *di8 = GetDirectInput();
|
||||||
Deactivate();
|
Deactivate();
|
||||||
|
if (!di8) return 0;
|
||||||
|
if (DI_OK != di8->CreateDevice(guidInstance, &did, 0)) {
|
||||||
|
ReleaseDirectInput();
|
||||||
|
did = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DIOBJECTDATAFORMAT *formats = (DIOBJECTDATAFORMAT*)malloc(sizeof(DIOBJECTDATAFORMAT) * numPhysicalControls);
|
||||||
|
for (i=0; i<numPhysicalControls; i++) {
|
||||||
|
formats[i].pguid = 0;
|
||||||
|
formats[i].dwType = physicalControls[i].type | DIDFT_MAKEINSTANCE(physicalControls[i].id);
|
||||||
|
formats[i].dwOfs = 4*i;
|
||||||
|
formats[i].dwFlags = 0;
|
||||||
|
}
|
||||||
|
DIDATAFORMAT format;
|
||||||
|
format.dwSize = sizeof(format);
|
||||||
|
format.dwDataSize = 4 * numPhysicalControls;
|
||||||
|
format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
|
||||||
|
format.dwFlags = 0;
|
||||||
|
format.dwNumObjs = numPhysicalControls;
|
||||||
|
format.rgodf = formats;
|
||||||
|
int res = did->SetDataFormat(&format);
|
||||||
|
for (i=0; i<numPhysicalControls; i++) {
|
||||||
|
if (physicalControls[i].type == ABSAXIS) {
|
||||||
|
DIPROPRANGE prop;
|
||||||
|
prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||||
|
prop.diph.dwSize = sizeof(DIPROPRANGE);
|
||||||
|
prop.diph.dwObj = formats[i].dwType;
|
||||||
|
prop.diph.dwHow = DIPH_BYID;
|
||||||
|
prop.lMin = -FULLY_DOWN;
|
||||||
|
prop.lMax = FULLY_DOWN;
|
||||||
|
did->SetProperty(DIPROP_RANGE, &prop.diph);
|
||||||
|
|
||||||
|
// May do something like this again, if there's any need.
|
||||||
|
/*
|
||||||
|
if (FAILED(DI->did->SetProperty(DIPROP_RANGE, &prop.diph))) {
|
||||||
|
if (FAILED(DI->did->GetProperty(DIPROP_RANGE, &prop.diph))) {
|
||||||
|
// ????
|
||||||
|
DI->objects[i].min = prop.lMin;
|
||||||
|
DI->objects[i].max = prop.lMax;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DI->objects[i].min = prop.lMin;
|
||||||
|
DI->objects[i].max = prop.lMax;
|
||||||
|
//*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(formats);
|
||||||
|
}
|
||||||
InitInfo *info = (InitInfo*)d;
|
InitInfo *info = (InitInfo*)d;
|
||||||
// Note: Have to use hWndTop to properly hide cursor for mouse device.
|
// Note: Have to use hWndTop to properly hide cursor for mouse device.
|
||||||
if (type == OTHER) {
|
if (type == OTHER) {
|
||||||
|
@ -165,6 +202,9 @@ public:
|
||||||
did->SetCooperativeLevel(info->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
|
did->SetCooperativeLevel(info->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
if (did->Acquire() != DI_OK) {
|
if (did->Acquire() != DI_OK) {
|
||||||
|
did->Release();
|
||||||
|
did = 0;
|
||||||
|
ReleaseDirectInput();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
AllocState();
|
AllocState();
|
||||||
|
@ -278,12 +318,13 @@ public:
|
||||||
}
|
}
|
||||||
if (active) {
|
if (active) {
|
||||||
did->Unacquire();
|
did->Unacquire();
|
||||||
|
did->Release();
|
||||||
|
ReleaseDirectInput();
|
||||||
active = 0;
|
active = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~DirectInputDevice() {
|
~DirectInputDevice() {
|
||||||
did->Release();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -376,15 +417,8 @@ BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOI
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CreationInfo {
|
|
||||||
LPDIRECTINPUT8 lpDI8;
|
|
||||||
int count;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
|
BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
|
||||||
CreationInfo *ci = (CreationInfo*) pvRef;
|
IDirectInput8* di8 = (IDirectInput8*)pvRef;
|
||||||
int *count = (int*) pvRef;
|
|
||||||
const wchar_t *name;
|
const wchar_t *name;
|
||||||
wchar_t temp[40];
|
wchar_t temp[40];
|
||||||
if (lpddi->tszInstanceName[0]) {
|
if (lpddi->tszInstanceName[0]) {
|
||||||
|
@ -394,10 +428,10 @@ BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
|
||||||
name = lpddi->tszProductName;
|
name = lpddi->tszProductName;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wsprintfW (temp, L"Device %i", ci->count);
|
wsprintfW (temp, L"Device %i", di8d.deviceCount);
|
||||||
name = temp;
|
name = temp;
|
||||||
}
|
}
|
||||||
ci->count++;
|
di8d.deviceCount++;
|
||||||
wchar_t *fullName = (wchar_t *) malloc((wcslen(name) + 4) * sizeof(wchar_t));
|
wchar_t *fullName = (wchar_t *) malloc((wcslen(name) + 4) * sizeof(wchar_t));
|
||||||
wsprintf(fullName, L"DX %s", name);
|
wsprintf(fullName, L"DX %s", name);
|
||||||
wchar_t instanceID[100];
|
wchar_t instanceID[100];
|
||||||
|
@ -412,17 +446,18 @@ BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
|
||||||
type = MOUSE;
|
type = MOUSE;
|
||||||
}
|
}
|
||||||
IDirectInputDevice8 *did;
|
IDirectInputDevice8 *did;
|
||||||
if (DI_OK == ci->lpDI8->CreateDevice(lpddi->guidInstance, &did, 0)) {
|
if (DI_OK == di8->CreateDevice(lpddi->guidInstance, &did, 0)) {
|
||||||
dm->AddDevice(new DirectInputDevice(type, did, fullName, instanceID, productID));
|
dm->AddDevice(new DirectInputDevice(type, did, fullName, instanceID, productID, lpddi->guidInstance));
|
||||||
}
|
}
|
||||||
free(fullName);
|
free(fullName);
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumDirectInputDevices() {
|
void EnumDirectInputDevices() {
|
||||||
CreationInfo ci = {0,0};
|
IDirectInput8* di8 = GetDirectInput();
|
||||||
if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void**) &ci.lpDI8, 0))) return;
|
if (!di8) return;
|
||||||
ci.lpDI8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, &ci, DIEDFL_ATTACHEDONLY);
|
di8d.deviceCount = 0;
|
||||||
ci.lpDI8->Release();
|
di8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, di8, DIEDFL_ATTACHEDONLY);
|
||||||
|
ReleaseDirectInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -487,7 +487,7 @@ u32 CALLBACK PS2EgetLibType(void) {
|
||||||
return PS2E_LT_PAD;
|
return PS2E_LT_PAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VERSION ((0<<8) | 9 | (9<<24))
|
#define VERSION ((0<<8) | 9 | (10<<24))
|
||||||
|
|
||||||
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
|
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
|
||||||
ps2e = 1;
|
ps2e = 1;
|
||||||
|
@ -644,7 +644,7 @@ ExtraWndProcResult HackWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||||
// Need to do this when not reading input from gs thread.
|
// Need to do this when not reading input from gs thread.
|
||||||
// Checking for that case not worth the effort.
|
// Checking for that case not worth the effort.
|
||||||
EnterCriticalSection(&readInputCriticalSection);
|
EnterCriticalSection(&readInputCriticalSection);
|
||||||
RefreshEnabledDevices(1);
|
UpdateEnabledDevices(1);
|
||||||
LeaveCriticalSection(&readInputCriticalSection);
|
LeaveCriticalSection(&readInputCriticalSection);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue