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:
mattmenke 2009-02-21 19:41:30 +00:00
parent a22035664d
commit 6ecd052079
2 changed files with 100 additions and 65 deletions

View File

@ -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();
} }

View File

@ -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;