PAD: windows: clang-format

This commit is contained in:
Gauvain 'GovanifY' Roussel-Tarbouriech 2020-12-12 09:51:22 +01:00 committed by lightningterror
parent 9cdc963c97
commit 8067a480c7
31 changed files with 7710 additions and 6618 deletions

View File

@ -29,9 +29,12 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
int i; int i;
HWND hWndList = GetDlgItem(hWnd, IDC_DIAG_LIST); HWND hWndList = GetDlgItem(hWnd, IDC_DIAG_LIST);
static int fullRefresh; static int fullRefresh;
if (dev) { if (dev)
switch (uMsg) { {
case WM_INITDIALOG: { switch (uMsg)
{
case WM_INITDIALOG:
{
fullRefresh = 1; fullRefresh = 1;
SetWindowText(hWnd, dev->displayName); SetWindowText(hWnd, dev->displayName);
LVCOLUMNW c; LVCOLUMNW c;
@ -46,7 +49,8 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
LVITEM item; LVITEM item;
item.mask = LVIF_TEXT; item.mask = LVIF_TEXT;
item.iSubItem = 0; item.iSubItem = 0;
for (i = 0; i < dev->numVirtualControls; i++) { for (i = 0; i < dev->numVirtualControls; i++)
{
item.pszText = dev->GetVirtualControlName(dev->virtualControls + i); item.pszText = dev->GetVirtualControlName(dev->virtualControls + i);
item.iItem = i; item.iItem = i;
ListView_InsertItem(hWndList, &item); ListView_InsertItem(hWndList, &item);
@ -54,7 +58,8 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
SetTimer(hWnd, 1, 200, 0); SetTimer(hWnd, 1, 200, 0);
} }
//break; //break;
case WM_TIMER: { case WM_TIMER:
{
hWndButtonProc.SetWndHandle(hWndList); hWndButtonProc.SetWndHandle(hWndList);
InitInfo info = {0, 1, hWnd, &hWndButtonProc}; InitInfo info = {0, 1, hWnd, &hWndButtonProc};
dm->Update(&info); dm->Update(&info);
@ -63,29 +68,40 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
item.iSubItem = 1; item.iSubItem = 1;
//ShowWindow(hWndList, 0); //ShowWindow(hWndList, 0);
//LockWindowUpdate(hWndList); //LockWindowUpdate(hWndList);
if (!dev->active) { if (!dev->active)
{
item.pszText = L"N/A"; item.pszText = L"N/A";
for (i = 0; i < dev->numVirtualControls; i++) { for (i = 0; i < dev->numVirtualControls; i++)
{
item.iItem = i; item.iItem = i;
ListView_SetItem(hWndList, &item); ListView_SetItem(hWndList, &item);
} }
fullRefresh = 1; fullRefresh = 1;
} else { }
for (i = 0; i < dev->numVirtualControls; i++) { else
if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i]) { {
for (i = 0; i < dev->numVirtualControls; i++)
{
if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i])
{
VirtualControl* c = dev->virtualControls + i; VirtualControl* c = dev->virtualControls + i;
wchar_t temp[50]; wchar_t temp[50];
int val = dev->virtualControlState[i]; int val = dev->virtualControlState[i];
if (c->uid & (UID_POV)) { if (c->uid & (UID_POV))
{
wsprintfW(temp, L"%i", val); wsprintfW(temp, L"%i", val);
} else { }
else
{
wchar_t* sign = L""; wchar_t* sign = L"";
if (val < 0) { if (val < 0)
{
sign = L"-"; sign = L"-";
val = -val; val = -val;
} }
if ((c->uid & UID_AXIS) && val) { if ((c->uid & UID_AXIS) && val)
{
val = val; val = val;
} }
val = (int)floor(0.5 + val * 1000.0 / (double)FULLY_DOWN); val = (int)floor(0.5 + val * 1000.0 / (double)FULLY_DOWN);
@ -102,8 +118,10 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
//LockWindowUpdate(0); //LockWindowUpdate(0);
//ShowWindow(hWndList, 1); //ShowWindow(hWndList, 1);
//UpdateWindow(hWnd); //UpdateWindow(hWnd);
} break; }
case WM_NOTIFY: { break;
case WM_NOTIFY:
{
NMLVKEYDOWN* n = (NMLVKEYDOWN*)lParam; NMLVKEYDOWN* n = (NMLVKEYDOWN*)lParam;
// Don't always get the notification when testing DirectInput non-keyboard devices. // Don't always get the notification when testing DirectInput non-keyboard devices.
// Don't get it (Or want it) when testing keyboards. // Don't get it (Or want it) when testing keyboards.
@ -132,7 +150,8 @@ void Diagnose(int id, HWND hWnd)
{ {
// init = 0; // init = 0;
dev = dm->devices[id]; dev = dm->devices[id];
for (int i = 0; i < dm->numDevices; i++) { for (int i = 0; i < dm->numDevices; i++)
{
if (i != id) if (i != id)
dm->DisableDevice(i); dm->DisableDevice(i);
// Shouldn't be needed. // Shouldn't be needed.

View File

@ -34,7 +34,8 @@
#ifndef SAFE_RELEASE #ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) \ #define SAFE_RELEASE(p) \
{ \ { \
if (p) { \ if (p) \
{ \
(p)->Release(); \ (p)->Release(); \
(p) = NULL; \ (p) = NULL; \
} \ } \
@ -73,7 +74,8 @@ DirectInput8Data di8d = {0, 0, 0};
IDirectInput8* GetDirectInput() IDirectInput8* GetDirectInput()
{ {
if (!di8d.lpDI8) { if (!di8d.lpDI8)
{
if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void**)&di8d.lpDI8, 0))) if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void**)&di8d.lpDI8, 0)))
return 0; return 0;
} }
@ -82,9 +84,11 @@ IDirectInput8 *GetDirectInput()
} }
void ReleaseDirectInput() void ReleaseDirectInput()
{ {
if (di8d.refCount) { if (di8d.refCount)
{
di8d.refCount--; di8d.refCount--;
if (!di8d.refCount) { if (!di8d.refCount)
{
di8d.lpDI8->Release(); di8d.lpDI8->Release();
di8d.lpDI8 = 0; di8d.lpDI8 = 0;
} }
@ -97,7 +101,8 @@ static int StringToGUID(GUID *pg, wchar_t *dataw)
if (wcslen(dataw) > 50) if (wcslen(dataw) > 50)
return 0; return 0;
int w = 0; int w = 0;
while (dataw[w]) { while (dataw[w])
{
data[w] = (char)dataw[w]; data[w] = (char)dataw[w];
w++; w++;
} }
@ -144,14 +149,18 @@ public:
void SetEffect(ForceFeedbackBinding* binding, unsigned char force) void SetEffect(ForceFeedbackBinding* binding, unsigned char force)
{ {
int index = 0; int index = 0;
if (!diEffects) { if (!diEffects)
{
return; return;
} }
for (int port = 0; port < 2; port++) { for (int port = 0; port < 2; port++)
for (int slot = 0; slot < 4; slot++) { {
for (int slot = 0; slot < 4; slot++)
{
int padtype = config.padConfigs[port][slot].type; int padtype = config.padConfigs[port][slot].type;
unsigned int diff = binding - pads[port][slot][padtype].ffBindings; unsigned int diff = binding - pads[port][slot][padtype].ffBindings;
if (diff < (unsigned int)pads[port][slot][padtype].numFFBindings) { if (diff < (unsigned int)pads[port][slot][padtype].numFFBindings)
{
index += diff; index += diff;
port = 2; port = 2;
break; break;
@ -160,7 +169,8 @@ public:
} }
} }
IDirectInputEffect* die = diEffects[index].die; IDirectInputEffect* die = diEffects[index].die;
if (die) { if (die)
{
DIEFFECT dieffect; DIEFFECT dieffect;
memset(&dieffect, 0, sizeof(dieffect)); memset(&dieffect, 0, sizeof(dieffect));
union union
@ -176,16 +186,21 @@ public:
if (magnitude > 10000) if (magnitude > 10000)
magnitude = 10000; magnitude = 10000;
int type = ffEffectTypes[binding->effectIndex].type; int type = ffEffectTypes[binding->effectIndex].type;
if (type == EFFECT_CONSTANT) { if (type == EFFECT_CONSTANT)
{
dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
constant.lMagnitude = magnitude; constant.lMagnitude = magnitude;
} else if (type == EFFECT_PERIODIC) { }
else if (type == EFFECT_PERIODIC)
{
dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC); dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC);
periodic.dwMagnitude = 0; periodic.dwMagnitude = 0;
periodic.lOffset = magnitude; periodic.lOffset = magnitude;
periodic.dwPhase = 0; periodic.dwPhase = 0;
periodic.dwPeriod = 2000000; periodic.dwPeriod = 2000000;
} else if (type == EFFECT_RAMP) { }
else if (type == EFFECT_RAMP)
{
dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE); dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
ramp.lEnd = ramp.lStart = magnitude; ramp.lEnd = ramp.lStart = magnitude;
} }
@ -202,7 +217,8 @@ public:
Deactivate(); Deactivate();
if (!di8) if (!di8)
return 0; return 0;
if (DI_OK != di8->CreateDevice(guidInstance, &did, 0)) { if (DI_OK != di8->CreateDevice(guidInstance, &did, 0))
{
ReleaseDirectInput(); ReleaseDirectInput();
did = 0; did = 0;
return 0; return 0;
@ -210,7 +226,8 @@ public:
{ {
DIOBJECTDATAFORMAT* formats = (DIOBJECTDATAFORMAT*)calloc(numPhysicalControls, sizeof(DIOBJECTDATAFORMAT)); DIOBJECTDATAFORMAT* formats = (DIOBJECTDATAFORMAT*)calloc(numPhysicalControls, sizeof(DIOBJECTDATAFORMAT));
for (i = 0; i < numPhysicalControls; i++) { for (i = 0; i < numPhysicalControls; i++)
{
formats[i].dwType = physicalControls[i].type | DIDFT_MAKEINSTANCE(physicalControls[i].id); formats[i].dwType = physicalControls[i].type | DIDFT_MAKEINSTANCE(physicalControls[i].id);
formats[i].dwOfs = 4 * i; formats[i].dwOfs = 4 * i;
} }
@ -222,8 +239,10 @@ public:
format.dwNumObjs = numPhysicalControls; format.dwNumObjs = numPhysicalControls;
format.rgodf = formats; format.rgodf = formats;
int res = did->SetDataFormat(&format); int res = did->SetDataFormat(&format);
for (i = 0; i < numPhysicalControls; i++) { for (i = 0; i < numPhysicalControls; i++)
if (physicalControls[i].type == ABSAXIS) { {
if (physicalControls[i].type == ABSAXIS)
{
DIPROPRANGE prop; DIPROPRANGE prop;
prop.diph.dwHeaderSize = sizeof(DIPROPHEADER); prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
prop.diph.dwSize = sizeof(DIPROPRANGE); prop.diph.dwSize = sizeof(DIPROPRANGE);
@ -251,14 +270,20 @@ public:
free(formats); free(formats);
} }
// 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)
{
did->SetCooperativeLevel(initInfo->hWndTop, DISCL_BACKGROUND | DISCL_EXCLUSIVE); did->SetCooperativeLevel(initInfo->hWndTop, DISCL_BACKGROUND | DISCL_EXCLUSIVE);
} else if (type == KEYBOARD) { }
else if (type == KEYBOARD)
{
did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND); did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND);
} else { }
else
{
did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE); did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
} }
if (did->Acquire() != DI_OK) { if (did->Acquire() != DI_OK)
{
did->Release(); did->Release();
did = 0; did = 0;
ReleaseDirectInput(); ReleaseDirectInput();
@ -268,11 +293,14 @@ public:
int count = GetFFBindingCount(); int count = GetFFBindingCount();
diEffects = (DI8Effect*)calloc(count, sizeof(DI8Effect)); diEffects = (DI8Effect*)calloc(count, sizeof(DI8Effect));
i = 0; i = 0;
for (int port = 0; port < 2; port++) { for (int port = 0; port < 2; port++)
for (int slot = 0; slot < 4; slot++) { {
for (int slot = 0; slot < 4; slot++)
{
int padtype = config.padConfigs[port][slot].type; int padtype = config.padConfigs[port][slot].type;
int subIndex = i; int subIndex = i;
for (int j = 0; j < pads[port][slot][padtype].numFFBindings; j++) { for (int j = 0; j < pads[port][slot][padtype].numFFBindings; j++)
{
ForceFeedbackBinding* b = 0; ForceFeedbackBinding* b = 0;
b = &pads[port][slot][padtype].ffBindings[i - subIndex]; b = &pads[port][slot][padtype].ffBindings[i - subIndex];
ForceFeedbackEffectType* eff = ffEffectTypes + b->effectIndex; ForceFeedbackEffectType* eff = ffEffectTypes + b->effectIndex;
@ -294,11 +322,16 @@ public:
DICONSTANTFORCE constant; DICONSTANTFORCE constant;
} stuff = {0, 0, 0, 0}; } stuff = {0, 0, 0, 0};
if (eff->type == EFFECT_CONSTANT) { if (eff->type == EFFECT_CONSTANT)
{
dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
} else if (eff->type == EFFECT_PERIODIC) { }
else if (eff->type == EFFECT_PERIODIC)
{
dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC); dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC);
} else if (eff->type == EFFECT_RAMP) { }
else if (eff->type == EFFECT_RAMP)
{
dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE); dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
} }
dieffect.lpvTypeSpecificParams = &stuff; dieffect.lpvTypeSpecificParams = &stuff;
@ -310,10 +343,13 @@ public:
LONG* dirList = (LONG*)(axisIDs + numFFAxes); LONG* dirList = (LONG*)(axisIDs + numFFAxes);
dieffect.rgdwAxes = axisIDs; dieffect.rgdwAxes = axisIDs;
dieffect.rglDirection = dirList; dieffect.rglDirection = dirList;
for (int k = 0; k < numFFAxes; k++) { for (int k = 0; k < numFFAxes; k++)
if (b->axes[k].force) { {
if (b->axes[k].force)
{
int force = abs(b->axes[k].force); int force = abs(b->axes[k].force);
if (force > maxForce) { if (force > maxForce)
{
maxForce = force; maxForce = force;
} }
axes[numAxes] = k; axes[numAxes] = k;
@ -322,13 +358,15 @@ public:
numAxes++; numAxes++;
} }
} }
if (!numAxes) { if (!numAxes)
{
free(axes); free(axes);
continue; continue;
} }
dieffect.cAxes = numAxes; dieffect.cAxes = numAxes;
diEffects[i].scale = maxForce; diEffects[i].scale = maxForce;
if (!SUCCEEDED(did->CreateEffect(guid, &dieffect, &diEffects[i].die, 0))) { if (!SUCCEEDED(did->CreateEffect(guid, &dieffect, &diEffects[i].die, 0)))
{
diEffects[i].die = 0; diEffects[i].die = 0;
diEffects[i].scale = 0; diEffects[i].scale = 0;
} }
@ -347,18 +385,24 @@ public:
{ {
if (!active) if (!active)
return 0; return 0;
if (numPhysicalControls) { if (numPhysicalControls)
{
HRESULT res = did->Poll(); HRESULT res = did->Poll();
// ?? // ??
if ((res != DI_OK && res != DI_NOEFFECT) || if ((res != DI_OK && res != DI_NOEFFECT) ||
DI_OK != did->GetDeviceState(4 * numPhysicalControls, physicalControlState)) { DI_OK != did->GetDeviceState(4 * numPhysicalControls, physicalControlState))
{
Deactivate(); Deactivate();
return 0; return 0;
} }
for (int i = 0; i < numPhysicalControls; i++) { for (int i = 0; i < numPhysicalControls; i++)
if (physicalControls[i].type & RELAXIS) { {
if (physicalControls[i].type & RELAXIS)
{
physicalControlState[i] *= (FULLY_DOWN / 3); physicalControlState[i] *= (FULLY_DOWN / 3);
} else if (physicalControls[i].type & BUTTON) { }
else if (physicalControls[i].type & BUTTON)
{
physicalControlState[i] = (physicalControlState[i] & 0x80) * FULLY_DOWN / 128; physicalControlState[i] = (physicalControlState[i] & 0x80) * FULLY_DOWN / 128;
} }
} }
@ -369,8 +413,10 @@ public:
int GetFFBindingCount() int GetFFBindingCount()
{ {
int count = 0; int count = 0;
for (int port = 0; port < 2; port++) { for (int port = 0; port < 2; port++)
for (int slot = 0; slot < 4; slot++) { {
for (int slot = 0; slot < 4; slot++)
{
int padtype = config.padConfigs[port][slot].type; int padtype = config.padConfigs[port][slot].type;
count += pads[port][slot][padtype].numFFBindings; count += pads[port][slot][padtype].numFFBindings;
} }
@ -381,10 +427,13 @@ public:
void Deactivate() void Deactivate()
{ {
FreeState(); FreeState();
if (diEffects) { if (diEffects)
{
int count = GetFFBindingCount(); int count = GetFFBindingCount();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++)
if (diEffects[i].die) { {
if (diEffects[i].die)
{
diEffects[i].die->Stop(); diEffects[i].die->Stop();
diEffects[i].die->Release(); diEffects[i].die->Release();
} }
@ -392,7 +441,8 @@ public:
free(diEffects); free(diEffects);
diEffects = 0; diEffects = 0;
} }
if (active) { if (active)
{
did->Unacquire(); did->Unacquire();
did->Release(); did->Release();
ReleaseDirectInput(); ReleaseDirectInput();
@ -411,13 +461,20 @@ BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef)
DirectInputDevice* did = (DirectInputDevice*)pvRef; DirectInputDevice* did = (DirectInputDevice*)pvRef;
EffectType type; EffectType type;
int diType = DIEFT_GETTYPE(pdei->dwEffType); int diType = DIEFT_GETTYPE(pdei->dwEffType);
if (diType == DIEFT_CONSTANTFORCE) { if (diType == DIEFT_CONSTANTFORCE)
{
type = EFFECT_CONSTANT; type = EFFECT_CONSTANT;
} else if (diType == DIEFT_RAMPFORCE) { }
else if (diType == DIEFT_RAMPFORCE)
{
type = EFFECT_RAMP; type = EFFECT_RAMP;
} else if (diType == DIEFT_PERIODIC) { }
else if (diType == DIEFT_PERIODIC)
{
type = EFFECT_PERIODIC; type = EFFECT_PERIODIC;
} else { }
else
{
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
wchar_t guidString[50]; wchar_t guidString[50];
@ -430,7 +487,8 @@ BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef)
BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
{ {
DirectInputDevice* did = (DirectInputDevice*)pvRef; DirectInputDevice* did = (DirectInputDevice*)pvRef;
if (lpddoi->dwType & DIDFT_FFACTUATOR) { if (lpddoi->dwType & DIDFT_FFACTUATOR)
{
did->AddFFAxis(lpddoi->tszName, lpddoi->dwType); did->AddFFAxis(lpddoi->tszName, lpddoi->dwType);
} }
@ -449,14 +507,17 @@ BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID
else else
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
// If too many objects, ignore extra buttons. // If too many objects, ignore extra buttons.
if ((did->numPhysicalControls > 255 && DIDFT_GETINSTANCE(lpddoi->dwType) > 255) && (type & (DIDFT_PSHBUTTON | DIDFT_TGLBUTTON))) { if ((did->numPhysicalControls > 255 && DIDFT_GETINSTANCE(lpddoi->dwType) > 255) && (type & (DIDFT_PSHBUTTON | DIDFT_TGLBUTTON)))
{
int i; int i;
for (i = did->numPhysicalControls - 1; i > did->numPhysicalControls - 4; i--) { for (i = did->numPhysicalControls - 1; i > did->numPhysicalControls - 4; i--)
{
if (!lpddoi->tszName[0]) if (!lpddoi->tszName[0])
break; break;
const wchar_t* s1 = lpddoi->tszName; const wchar_t* s1 = lpddoi->tszName;
const wchar_t* s2 = did->physicalControls[i].name; const wchar_t* s2 = did->physicalControls[i].name;
while (*s1 && *s1 == *s2) { while (*s1 && *s1 == *s2)
{
s1++; s1++;
s2++; s2++;
} }
@ -467,11 +528,13 @@ BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID
while (s1 != lpddoi->tszName && (s1[-1] >= '0' && s1[-1] <= '9')) while (s1 != lpddoi->tszName && (s1[-1] >= '0' && s1[-1] <= '9'))
s1--; s1--;
int check = 0; int check = 0;
while (*s1 >= '0' && *s1 <= '9') { while (*s1 >= '0' && *s1 <= '9')
{
check = check * 10 + *s1 - '0'; check = check * 10 + *s1 - '0';
s1++; s1++;
} }
while (*s2 >= '0' && *s2 <= '9') { while (*s2 >= '0' && *s2 <= '9')
{
s2++; s2++;
} }
// If perfect match other than final number > 30, then break. // If perfect match other than final number > 30, then break.
@ -479,16 +542,20 @@ BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID
if (!*s1 && !*s2 && check > 30) if (!*s1 && !*s2 && check > 30)
break; break;
} }
if (i != did->numPhysicalControls - 4) { if (i != did->numPhysicalControls - 4)
{
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
} }
int vkey = 0; int vkey = 0;
if (lpddoi->tszName[0] && did->type == KEYBOARD) { if (lpddoi->tszName[0] && did->type == KEYBOARD)
for (u32 i = 0; i < 256; i++) { {
for (u32 i = 0; i < 256; i++)
{
wchar_t* t = GetVKStringW((u8)i); wchar_t* t = GetVKStringW((u8)i);
if (!wcsicmp(lpddoi->tszName, t)) { if (!wcsicmp(lpddoi->tszName, t))
{
vkey = i; vkey = i;
break; break;
} }
@ -553,7 +620,8 @@ BOOL IsXInputDevice(const GUID *pGuidProductFromDirectInput)
goto LCleanup; goto LCleanup;
// Loop over all devices // Loop over all devices
for (;;) { for (;;)
{
// Get 20 at a time // Get 20 at a time
hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned); hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned);
if (FAILED(hr)) if (FAILED(hr))
@ -561,27 +629,33 @@ BOOL IsXInputDevice(const GUID *pGuidProductFromDirectInput)
if (uReturned == 0) if (uReturned == 0)
break; break;
for (iDevice = 0; iDevice < uReturned; iDevice++) { for (iDevice = 0; iDevice < uReturned; iDevice++)
{
// For each device, get its device ID // For each device, get its device ID
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL); hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL);
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != 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 // Check if the device ID contains "IG_". If it does, then it's an XInput device
// This information can not be found from DirectInput // This information can not be found from DirectInput
if (wcsstr(var.bstrVal, L"IG_")) { if (wcsstr(var.bstrVal, L"IG_"))
{
// If it does, then get the VID/PID from var.bstrVal // If it does, then get the VID/PID from var.bstrVal
DWORD dwPid = 0, dwVid = 0; DWORD dwPid = 0, dwVid = 0;
WCHAR* strVid = wcsstr(var.bstrVal, L"VID_"); WCHAR* strVid = wcsstr(var.bstrVal, L"VID_");
if (strVid) { if (strVid)
{
dwVid = wcstoul(strVid + 4, 0, 16); dwVid = wcstoul(strVid + 4, 0, 16);
} }
WCHAR* strPid = wcsstr(var.bstrVal, L"PID_"); WCHAR* strPid = wcsstr(var.bstrVal, L"PID_");
if (strPid) { if (strPid)
{
dwPid = wcstoul(strPid + 4, 0, 16); dwPid = wcstoul(strPid + 4, 0, 16);
} }
// Compare the VID/PID to the DInput device // Compare the VID/PID to the DInput device
DWORD dwVidPid = MAKELONG(dwVid, dwPid); DWORD dwVidPid = MAKELONG(dwVid, dwPid);
if (dwVidPid == pGuidProductFromDirectInput->Data1) { if (dwVidPid == pGuidProductFromDirectInput->Data1)
{
bIsXinputDevice = true; bIsXinputDevice = true;
goto LCleanup; goto LCleanup;
} }
@ -623,11 +697,16 @@ BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
const wchar_t* name; const wchar_t* name;
wchar_t temp[40]; wchar_t temp[40];
//if (((DeviceEnumInfo*)pvRef)->ignoreXInput && lpddi-> //if (((DeviceEnumInfo*)pvRef)->ignoreXInput && lpddi->
if (lpddi->tszInstanceName[0]) { if (lpddi->tszInstanceName[0])
{
name = lpddi->tszInstanceName; name = lpddi->tszInstanceName;
} else if (lpddi->tszProductName[0]) { }
else if (lpddi->tszProductName[0])
{
name = lpddi->tszProductName; name = lpddi->tszProductName;
} else { }
else
{
wsprintfW(temp, L"Device %i", di8d.deviceCount); wsprintfW(temp, L"Device %i", di8d.deviceCount);
name = temp; name = temp;
} }
@ -639,17 +718,24 @@ BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
GUIDtoString(instanceID, &lpddi->guidInstance); GUIDtoString(instanceID, &lpddi->guidInstance);
GUIDtoString(productID, &lpddi->guidProduct); GUIDtoString(productID, &lpddi->guidProduct);
DeviceType type = OTHER; DeviceType type = OTHER;
if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD) { if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD)
{
type = KEYBOARD; type = KEYBOARD;
} else if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_MOUSE) { }
else if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_MOUSE)
{
type = MOUSE; type = MOUSE;
} }
IDirectInputDevice8* did; IDirectInputDevice8* did;
if (DI_OK == di8->CreateDevice(lpddi->guidInstance, &did, 0)) { if (DI_OK == di8->CreateDevice(lpddi->guidInstance, &did, 0))
{
DirectInputDevice* dev = new DirectInputDevice(type, did, fullName, instanceID, productID, lpddi->guidInstance); DirectInputDevice* dev = new DirectInputDevice(type, did, fullName, instanceID, productID, lpddi->guidInstance);
if (dev->numPhysicalControls || dev->numFFAxes) { if (dev->numPhysicalControls || dev->numFFAxes)
{
dm->AddDevice(dev); dm->AddDevice(dev);
} else { }
else
{
delete dev; delete dev;
} }
} }

View File

@ -64,7 +64,8 @@ HMODULE hModLibusb = 0;
void UninitLibUsb() void UninitLibUsb()
{ {
if (hModLibusb) { if (hModLibusb)
{
FreeLibrary(hModLibusb); FreeLibrary(hModLibusb);
hModLibusb = 0; hModLibusb = 0;
} }
@ -72,10 +73,13 @@ void UninitLibUsb()
void TryInitDS3(usb_device* dev) void TryInitDS3(usb_device* dev)
{ {
while (dev) { while (dev)
if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) { {
if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID)
{
usb_dev_handle* handle = pusb_open(dev); usb_dev_handle* handle = pusb_open(dev);
if (handle) { if (handle)
{
char junk[20]; char junk[20];
// This looks like HidD_GetFeature with a feature report id of 0xF2 to me and a length of 17. // 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. // That doesn't work, however, and 17 is shorter than the report length.
@ -83,8 +87,10 @@ void TryInitDS3(usb_device *dev)
pusb_close(handle); pusb_close(handle);
} }
} }
if (dev->num_children) { if (dev->num_children)
for (int i = 0; i < dev->num_children; i++) { {
for (int i = 0; i < dev->num_children; i++)
{
TryInitDS3(dev->children[i]); TryInitDS3(dev->children[i]);
} }
} }
@ -94,7 +100,8 @@ void TryInitDS3(usb_device *dev)
void DS3Enum(unsigned int time) void DS3Enum(unsigned int time)
{ {
if (time - lastDS3Enum < DOUBLE_ENUM_DELAY) { if (time - lastDS3Enum < DOUBLE_ENUM_DELAY)
{
return; return;
} }
lastDS3Enum = time; lastDS3Enum = time;
@ -104,16 +111,19 @@ void DS3Enum(unsigned int time)
void DS3Check(unsigned int time) void DS3Check(unsigned int time)
{ {
if (time - lastDS3Check < DOUBLE_CHECK_DELAY) { if (time - lastDS3Check < DOUBLE_CHECK_DELAY)
{
return; return;
} }
if (!lastDS3Check) { if (!lastDS3Check)
{
DS3Enum(time); DS3Enum(time);
} }
lastDS3Check = time; lastDS3Check = time;
usb_bus* bus = pusb_get_busses(); usb_bus* bus = pusb_get_busses();
while (bus) { while (bus)
{
TryInitDS3(bus->devices); TryInitDS3(bus->devices);
bus = bus->next; bus = bus->next;
} }
@ -121,11 +131,13 @@ void DS3Check(unsigned int time)
int InitLibUsb() int InitLibUsb()
{ {
if (hModLibusb) { if (hModLibusb)
{
return 1; return 1;
} }
hModLibusb = LoadLibraryA("C:\\windows\\system32\\libusb0.dll"); hModLibusb = LoadLibraryA("C:\\windows\\system32\\libusb0.dll");
if (hModLibusb) { if (hModLibusb)
{
if ((pusb_init = (_usb_init)GetProcAddress(hModLibusb, "usb_init")) && if ((pusb_init = (_usb_init)GetProcAddress(hModLibusb, "usb_init")) &&
(pusb_close = (_usb_close)GetProcAddress(hModLibusb, "usb_close")) && (pusb_close = (_usb_close)GetProcAddress(hModLibusb, "usb_close")) &&
(pusb_get_string_simple = (_usb_get_string_simple)GetProcAddress(hModLibusb, "usb_get_string_simple")) && (pusb_get_string_simple = (_usb_get_string_simple)GetProcAddress(hModLibusb, "usb_get_string_simple")) &&
@ -133,7 +145,8 @@ int InitLibUsb()
(pusb_find_busses = (_usb_find_busses)GetProcAddress(hModLibusb, "usb_find_busses")) && (pusb_find_busses = (_usb_find_busses)GetProcAddress(hModLibusb, "usb_find_busses")) &&
(pusb_find_devices = (_usb_find_devices)GetProcAddress(hModLibusb, "usb_find_devices")) && (pusb_find_devices = (_usb_find_devices)GetProcAddress(hModLibusb, "usb_find_devices")) &&
(pusb_get_busses = (_usb_get_busses)GetProcAddress(hModLibusb, "usb_get_busses")) && (pusb_get_busses = (_usb_get_busses)GetProcAddress(hModLibusb, "usb_get_busses")) &&
(pusb_control_msg = (_usb_control_msg)GetProcAddress(hModLibusb, "usb_control_msg"))) { (pusb_control_msg = (_usb_control_msg)GetProcAddress(hModLibusb, "usb_control_msg")))
{
pusb_init(); pusb_init();
return 1; return 1;
} }
@ -227,7 +240,8 @@ public:
void QueueWrite() void QueueWrite()
{ {
// max of 2 queued writes allowed, one for either motor. // max of 2 queued writes allowed, one for either motor.
if (writeQueued < 2) { if (writeQueued < 2)
{
writeQueued++; writeQueued++;
StartWrite(); StartWrite();
} }
@ -235,7 +249,8 @@ public:
int StartWrite() int StartWrite()
{ {
if (!writing && writeQueued) { if (!writing && writeQueued)
{
lastWrite = GetTickCount(); lastWrite = GetTickCount();
writing++; writing++;
writeQueued--; writeQueued--;
@ -248,7 +263,8 @@ public:
sendState.motors[1].force = (unsigned char)bigForce; sendState.motors[1].force = (unsigned char)bigForce;
sendState.motors[0].force = (unsigned char)(vibration[1] >= FULLY_DOWN / 2); sendState.motors[0].force = (unsigned char)(vibration[1] >= FULLY_DOWN / 2);
// Can't seem to have them both non-zero at once. // Can't seem to have them both non-zero at once.
if (sendState.motors[writeCount & 1].force) { if (sendState.motors[writeCount & 1].force)
{
sendState.motors[(writeCount & 1) ^ 1].force = 0; sendState.motors[(writeCount & 1) ^ 1].force = 0;
sendState.motors[(writeCount & 1) ^ 1].duration = 0; sendState.motors[(writeCount & 1) ^ 1].duration = 0;
} }
@ -279,14 +295,19 @@ public:
vibration[0] = vibration[1] = 0; vibration[0] = vibration[1] = 0;
this->index = index; this->index = index;
int i; int i;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++)
if (i != 14 && i != 15 && i != 8 && i != 9) { {
if (i != 14 && i != 15 && i != 8 && i != 9)
{
AddPhysicalControl(PRESSURE_BTN, i, 0); AddPhysicalControl(PRESSURE_BTN, i, 0);
} else { }
else
{
AddPhysicalControl(PSHBTN, i, 0); AddPhysicalControl(PSHBTN, i, 0);
} }
} }
for (; i < 23; i++) { for (; i < 23; i++)
{
AddPhysicalControl(ABSAXIS, i, 0); AddPhysicalControl(ABSAXIS, i, 0);
} }
AddFFAxis(L"Big Motor", 0); AddFFAxis(L"Big Motor", 0);
@ -323,7 +344,8 @@ public:
L"???", L"???",
}; };
unsigned int i = (unsigned int)(c - physicalControls); unsigned int i = (unsigned int)(c - physicalControls);
if (i < sizeof(names) / sizeof(names[0])) { if (i < sizeof(names) / sizeof(names[0]))
{
return (wchar_t*)names[i]; return (wchar_t*)names[i];
} }
return Device::GetPhysicalControlName(c); return Device::GetPhysicalControlName(c);
@ -339,7 +361,8 @@ public:
writeop.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); 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 || if (!readop.hEvent || !writeop.hEvent || hFile == INVALID_HANDLE_VALUE ||
!StartRead()) { !StartRead())
{
Deactivate(); Deactivate();
return 0; return 0;
} }
@ -356,14 +379,18 @@ public:
readop.hEvent, readop.hEvent,
writeop.hEvent}; writeop.hEvent};
unsigned int time = GetTickCount(); unsigned int time = GetTickCount();
if (time - lastWrite > UPDATE_INTERVAL) { if (time - lastWrite > UPDATE_INTERVAL)
{
QueueWrite(); QueueWrite();
} }
while (1) { while (1)
{
DWORD res = WaitForMultipleObjects(2, h, 0, 0); DWORD res = WaitForMultipleObjects(2, h, 0, 0);
if (res == WAIT_OBJECT_0) { if (res == WAIT_OBJECT_0)
{
dataLastReceived = time; dataLastReceived = time;
if (!StartRead()) { if (!StartRead())
{
Deactivate(); Deactivate();
return 0; return 0;
} }
@ -392,18 +419,26 @@ public:
physicalControlState[21] = CharToAxis(getState[44] + 128); physicalControlState[21] = CharToAxis(getState[44] + 128);
physicalControlState[22] = CharToAxis(getState[46] + 128); physicalControlState[22] = CharToAxis(getState[46] + 128);
continue; continue;
} else if (res == WAIT_OBJECT_0 + 1) { }
else if (res == WAIT_OBJECT_0 + 1)
{
writing = 0; writing = 0;
if (!writeQueued && (vibration[0] | vibration[1])) { if (!writeQueued && (vibration[0] | vibration[1]))
{
QueueWrite(); QueueWrite();
} }
if (!StartWrite()) { if (!StartWrite())
{
Deactivate(); Deactivate();
return 0; return 0;
} }
} else { }
if (time - dataLastReceived >= DEVICE_CHECK_DELAY) { else
if (time - dataLastReceived >= DEVICE_ENUM_DELAY) { {
if (time - dataLastReceived >= DEVICE_CHECK_DELAY)
{
if (time - dataLastReceived >= DEVICE_ENUM_DELAY)
{
DS3Enum(time); DS3Enum(time);
} }
DS3Check(time); DS3Check(time);
@ -419,10 +454,13 @@ public:
{ {
ps2Vibration[port][slot][motor] = force; ps2Vibration[port][slot][motor] = force;
vibration[0] = vibration[1] = 0; vibration[0] = vibration[1] = 0;
for (int p = 0; p < 2; p++) { for (int p = 0; p < 2; p++)
for (int s = 0; s < 4; s++) { {
for (int s = 0; s < 4; s++)
{
int padtype = config.padConfigs[p][s].type; int padtype = config.padConfigs[p][s].type;
for (int i = 0; i < pads[p][s][padtype].numFFBindings; i++) { 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. // 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]; ForceFeedbackBinding* ffb = &pads[p][s][padtype].ffBindings[i];
vibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); vibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
@ -446,15 +484,18 @@ public:
void Deactivate() void Deactivate()
{ {
if (hFile != INVALID_HANDLE_VALUE) { if (hFile != INVALID_HANDLE_VALUE)
{
CancelIo(hFile); CancelIo(hFile);
CloseHandle(hFile); CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE;
} }
if (readop.hEvent) { if (readop.hEvent)
{
CloseHandle(readop.hEvent); CloseHandle(readop.hEvent);
} }
if (writeop.hEvent) { if (writeop.hEvent)
{
CloseHandle(writeop.hEvent); CloseHandle(writeop.hEvent);
} }
writing = 0; writing = 0;
@ -482,10 +523,12 @@ void EnumDualShock3s()
if (!numDevs) if (!numDevs)
return; return;
int index = 0; int index = 0;
for (int i = 0; i < numDevs; i++) { for (int i = 0; i < numDevs; i++)
{
if (foundDevs[i].caps.FeatureReportByteLength == 49 && if (foundDevs[i].caps.FeatureReportByteLength == 49 &&
foundDevs[i].caps.InputReportByteLength == 49 && foundDevs[i].caps.InputReportByteLength == 49 &&
foundDevs[i].caps.OutputReportByteLength == 49) { foundDevs[i].caps.OutputReportByteLength == 49)
{
wchar_t temp[100]; wchar_t temp[100];
wsprintfW(temp, L"DualShock 3 #%i", index + 1); wsprintfW(temp, L"DualShock 3 #%i", index + 1);
dm->AddDevice(new DualShock3Device(index, temp, foundDevs[i].path)); dm->AddDevice(new DualShock3Device(index, temp, foundDevs[i].path));

View File

@ -26,10 +26,12 @@ int FindHids(HidDeviceInfo **foundDevs, int vid, int pid)
*foundDevs = 0; *foundDevs = 0;
HidD_GetHidGuid(&GUID_DEVINTERFACE_HID); HidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hdev != INVALID_HANDLE_VALUE) { if (hdev != INVALID_HANDLE_VALUE)
{
SP_DEVICE_INTERFACE_DATA devInterfaceData; SP_DEVICE_INTERFACE_DATA devInterfaceData;
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (int i = 0; SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVINTERFACE_HID, i, &devInterfaceData); i++) { for (int i = 0; SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVINTERFACE_HID, i, &devInterfaceData); i++)
{
DWORD size = 0; DWORD size = 0;
SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0); SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0);
@ -47,16 +49,22 @@ int FindHids(HidDeviceInfo **foundDevs, int vid, int pid)
continue; continue;
HANDLE hfile = CreateFile(devInterfaceDetails->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 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) { if (hfile != INVALID_HANDLE_VALUE)
{
HIDD_ATTRIBUTES attributes; HIDD_ATTRIBUTES attributes;
attributes.Size = sizeof(attributes); attributes.Size = sizeof(attributes);
if (HidD_GetAttributes(hfile, &attributes)) { if (HidD_GetAttributes(hfile, &attributes))
if (attributes.VendorID == vid && attributes.ProductID == pid) { {
if (attributes.VendorID == vid && attributes.ProductID == pid)
{
PHIDP_PREPARSED_DATA pData; PHIDP_PREPARSED_DATA pData;
HIDP_CAPS caps; HIDP_CAPS caps;
if (HidD_GetPreparsedData(hfile, &pData)) { if (HidD_GetPreparsedData(hfile, &pData))
if (HidP_GetCaps(pData, &caps) == HIDP_STATUS_SUCCESS) { {
if (numFoundDevs % 32 == 0) { if (HidP_GetCaps(pData, &caps) == HIDP_STATUS_SUCCESS)
{
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++]; HidDeviceInfo* dev = &foundDevs[0][numFoundDevs++];

View File

@ -28,7 +28,8 @@ InputDeviceManager::InputDeviceManager()
void InputDeviceManager::ClearDevices() void InputDeviceManager::ClearDevices()
{ {
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++)
{
delete devices[i]; delete devices[i];
} }
free(devices); free(devices);
@ -92,11 +93,15 @@ Device::~Device()
// Generally called by deactivate, but just in case... // Generally called by deactivate, but just in case...
FreeState(); FreeState();
int i; int i;
for (int port = 0; port < 2; port++) { for (int port = 0; port < 2; port++)
for (int slot = 0; slot < 4; slot++) { {
for (int padtype = 0; padtype < numPadTypes; padtype++) { for (int slot = 0; slot < 4; slot++)
{
for (int padtype = 0; padtype < numPadTypes; padtype++)
{
free(pads[port][slot][padtype].bindings); free(pads[port][slot][padtype].bindings);
for (i = 0; i < pads[port][slot][padtype].numFFBindings; i++) { for (i = 0; i < pads[port][slot][padtype].numFFBindings; i++)
{
free(pads[port][slot][padtype].ffBindings[i].axes); free(pads[port][slot][padtype].ffBindings[i].axes);
} }
free(pads[port][slot][padtype].ffBindings); free(pads[port][slot][padtype].ffBindings);
@ -105,7 +110,8 @@ Device::~Device()
} }
free(virtualControls); free(virtualControls);
for (i = numPhysicalControls - 1; i >= 0; i--) { for (i = numPhysicalControls - 1; i >= 0; i--)
{
if (physicalControls[i].name) if (physicalControls[i].name)
free(physicalControls[i].name); free(physicalControls[i].name);
} }
@ -114,14 +120,18 @@ Device::~Device()
free(displayName); free(displayName);
free(instanceID); free(instanceID);
free(productID); free(productID);
if (ffAxes) { if (ffAxes)
for (i = 0; i < numFFAxes; i++) { {
for (i = 0; i < numFFAxes; i++)
{
free(ffAxes[i].displayName); free(ffAxes[i].displayName);
} }
free(ffAxes); free(ffAxes);
} }
if (ffEffectTypes) { if (ffEffectTypes)
for (i = 0; i < numFFEffectTypes; i++) { {
for (i = 0; i < numFFEffectTypes; i++)
{
free(ffEffectTypes[i].displayName); free(ffEffectTypes[i].displayName);
free(ffEffectTypes[i].effectID); free(ffEffectTypes[i].effectID);
} }
@ -145,10 +155,14 @@ void Device::AddFFAxis(const wchar_t *displayName, int id)
ffAxes[numFFAxes].displayName = wcsdup(displayName); ffAxes[numFFAxes].displayName = wcsdup(displayName);
numFFAxes++; numFFAxes++;
int bindingsExist = 0; int bindingsExist = 0;
for (int port = 0; port < 2; port++) { for (int port = 0; port < 2; port++)
for (int slot = 0; slot < 4; slot++) { {
for (int padtype = 0; padtype < numPadTypes; padtype++) { for (int slot = 0; slot < 4; slot++)
for (int i = 0; i < pads[port][slot][padtype].numFFBindings; i++) { {
for (int padtype = 0; padtype < numPadTypes; padtype++)
{
for (int i = 0; i < pads[port][slot][padtype].numFFBindings; i++)
{
ForceFeedbackBinding* b = pads[port][slot][padtype].ffBindings + i; ForceFeedbackBinding* b = pads[port][slot][padtype].ffBindings + i;
b->axes = (AxisEffectInfo*)realloc(b->axes, sizeof(AxisEffectInfo) * (numFFAxes)); b->axes = (AxisEffectInfo*)realloc(b->axes, sizeof(AxisEffectInfo) * (numFFAxes));
memset(b->axes + (numFFAxes - 1), 0, sizeof(AxisEffectInfo)); memset(b->axes + (numFFAxes - 1), 0, sizeof(AxisEffectInfo));
@ -158,10 +172,12 @@ void Device::AddFFAxis(const wchar_t *displayName, int id)
} }
} }
// Generally the case when not loading a binding file. // Generally the case when not loading a binding file.
if (!bindingsExist) { if (!bindingsExist)
{
int i = numFFAxes - 1; int i = numFFAxes - 1;
ForceFeedbackAxis temp = ffAxes[i]; ForceFeedbackAxis temp = ffAxes[i];
while (i && temp.id < ffAxes[i - 1].id) { while (i && temp.id < ffAxes[i - 1].id)
{
ffAxes[i] = ffAxes[i - 1]; ffAxes[i] = ffAxes[i - 1];
i--; i--;
} }
@ -189,23 +205,30 @@ void Device::PostRead()
void Device::CalcVirtualState() void Device::CalcVirtualState()
{ {
for (int i = 0; i < numPhysicalControls; i++) { for (int i = 0; i < numPhysicalControls; i++)
{
PhysicalControl* c = physicalControls + i; PhysicalControl* c = physicalControls + i;
int index = c->baseVirtualControlIndex; int index = c->baseVirtualControlIndex;
int val = physicalControlState[i]; int val = physicalControlState[i];
if (c->type & BUTTON) { if (c->type & BUTTON)
{
virtualControlState[index] = val; virtualControlState[index] = val;
// DirectInput keyboard events only. // DirectInput keyboard events only.
if (this->api == DI && this->type == KEYBOARD) { if (this->api == DI && this->type == KEYBOARD)
if (!(virtualControlState[index] >> 15) != !(oldVirtualControlState[index] >> 15) && c->vkey) { {
if (!(virtualControlState[index] >> 15) != !(oldVirtualControlState[index] >> 15) && c->vkey)
{
// Check for alt-F4 to avoid toggling skip mode incorrectly. // Check for alt-F4 to avoid toggling skip mode incorrectly.
if (c->vkey == VK_F4) { if (c->vkey == VK_F4)
{
int i; int i;
for (i = 0; i < numPhysicalControls; i++) { for (i = 0; i < numPhysicalControls; i++)
{
if (virtualControlState[physicalControls[i].baseVirtualControlIndex] && if (virtualControlState[physicalControls[i].baseVirtualControlIndex] &&
(physicalControls[i].vkey == VK_MENU || (physicalControls[i].vkey == VK_MENU ||
physicalControls[i].vkey == VK_RMENU || physicalControls[i].vkey == VK_RMENU ||
physicalControls[i].vkey == VK_LMENU)) { physicalControls[i].vkey == VK_LMENU))
{
break; break;
} }
} }
@ -218,24 +241,31 @@ void Device::CalcVirtualState()
QueueKeyEvent(c->vkey, event); QueueKeyEvent(c->vkey, event);
} }
} }
} else if (c->type & ABSAXIS) { }
else if (c->type & ABSAXIS)
{
virtualControlState[index] = (val + FULLY_DOWN) / 2; virtualControlState[index] = (val + FULLY_DOWN) / 2;
// Positive. Overkill. // Positive. Overkill.
virtualControlState[index + 1] = (val & ~(val >> 31)); virtualControlState[index + 1] = (val & ~(val >> 31));
// Negative // Negative
virtualControlState[index + 2] = (-val & (val >> 31)); virtualControlState[index + 2] = (-val & (val >> 31));
} else if (c->type & RELAXIS) { }
else if (c->type & RELAXIS)
{
int delta = val - oldVirtualControlState[index]; int delta = val - oldVirtualControlState[index];
virtualControlState[index] = val; virtualControlState[index] = val;
// Positive // Positive
virtualControlState[index + 1] = (delta & ~(delta >> 31)); virtualControlState[index + 1] = (delta & ~(delta >> 31));
// Negative // Negative
virtualControlState[index + 2] = (-delta & (delta >> 31)); virtualControlState[index + 2] = (-delta & (delta >> 31));
} else if (c->type & POV) { }
else if (c->type & POV)
{
virtualControlState[index] = val; virtualControlState[index] = val;
int iSouth = 0; int iSouth = 0;
int iEast = 0; int iEast = 0;
if ((unsigned int)val <= 37000) { if ((unsigned int)val <= 37000)
{
double angle = val * (3.141592653589793 / 18000.0); double angle = val * (3.141592653589793 / 18000.0);
double East = sin(angle); double East = sin(angle);
double South = -cos(angle); double South = -cos(angle);
@ -259,7 +289,8 @@ void Device::CalcVirtualState()
VirtualControl* Device::GetVirtualControl(unsigned int uid) VirtualControl* Device::GetVirtualControl(unsigned int uid)
{ {
for (int i = 0; i < numVirtualControls; i++) { for (int i = 0; i < numVirtualControls; i++)
{
if (virtualControls[i].uid == uid) if (virtualControls[i].uid == uid)
return virtualControls + i; return virtualControls + i;
} }
@ -271,7 +302,8 @@ VirtualControl *Device::AddVirtualControl(unsigned int uid, int physicalControlI
// Not really necessary, as always call AllocState when activated, but doesn't hurt. // Not really necessary, as always call AllocState when activated, but doesn't hurt.
FreeState(); FreeState();
if (numVirtualControls % 16 == 0) { if (numVirtualControls % 16 == 0)
{
virtualControls = (VirtualControl*)realloc(virtualControls, sizeof(VirtualControl) * (numVirtualControls + 16)); virtualControls = (VirtualControl*)realloc(virtualControls, sizeof(VirtualControl) * (numVirtualControls + 16));
} }
VirtualControl* c = virtualControls + numVirtualControls; VirtualControl* c = virtualControls + numVirtualControls;
@ -288,7 +320,8 @@ PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id,
// Not really necessary, as always call AllocState when activated, but doesn't hurt. // Not really necessary, as always call AllocState when activated, but doesn't hurt.
FreeState(); FreeState();
if (numPhysicalControls % 16 == 0) { if (numPhysicalControls % 16 == 0)
{
physicalControls = (PhysicalControl*)realloc(physicalControls, sizeof(PhysicalControl) * (numPhysicalControls + 16)); physicalControls = (PhysicalControl*)realloc(physicalControls, sizeof(PhysicalControl) * (numPhysicalControls + 16));
} }
PhysicalControl* control = physicalControls + numPhysicalControls; PhysicalControl* control = physicalControls + numPhysicalControls;
@ -300,14 +333,19 @@ PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id,
control->name = wcsdup(name); control->name = wcsdup(name);
control->baseVirtualControlIndex = numVirtualControls; control->baseVirtualControlIndex = numVirtualControls;
unsigned int uid = id | (type << 16); unsigned int uid = id | (type << 16);
if (type & BUTTON) { if (type & BUTTON)
{
AddVirtualControl(uid, numPhysicalControls); AddVirtualControl(uid, numPhysicalControls);
control->vkey = vkey; control->vkey = vkey;
} else if (type & AXIS) { }
else if (type & AXIS)
{
AddVirtualControl(uid | UID_AXIS, numPhysicalControls); AddVirtualControl(uid | UID_AXIS, numPhysicalControls);
AddVirtualControl(uid | UID_AXIS_POS, numPhysicalControls); AddVirtualControl(uid | UID_AXIS_POS, numPhysicalControls);
AddVirtualControl(uid | UID_AXIS_NEG, numPhysicalControls); AddVirtualControl(uid | UID_AXIS_NEG, numPhysicalControls);
} else if (type & POV) { }
else if (type & POV)
{
AddVirtualControl(uid | UID_POV, numPhysicalControls); AddVirtualControl(uid | UID_POV, numPhysicalControls);
AddVirtualControl(uid | UID_POV_N, numPhysicalControls); AddVirtualControl(uid | UID_POV_N, numPhysicalControls);
AddVirtualControl(uid | UID_POV_E, numPhysicalControls); AddVirtualControl(uid | UID_POV_E, numPhysicalControls);
@ -321,9 +359,11 @@ PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id,
void Device::SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) void Device::SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force)
{ {
int padtype = config.padConfigs[port][slot].type; int padtype = config.padConfigs[port][slot].type;
for (int i = 0; i < pads[port][slot][padtype].numFFBindings; i++) { for (int i = 0; i < pads[port][slot][padtype].numFFBindings; i++)
{
ForceFeedbackBinding* binding = pads[port][slot][padtype].ffBindings + i; ForceFeedbackBinding* binding = pads[port][slot][padtype].ffBindings + i;
if (binding->motor == motor) { if (binding->motor == motor)
{
SetEffect(binding, force); SetEffect(binding, force);
} }
} }
@ -332,13 +372,20 @@ void Device::SetEffects(unsigned char port, unsigned int slot, unsigned char mot
wchar_t* GetDefaultControlName(unsigned short id, int type) wchar_t* GetDefaultControlName(unsigned short id, int type)
{ {
static wchar_t name[20]; static wchar_t name[20];
if (type & BUTTON) { if (type & BUTTON)
{
wsprintfW(name, L"Button %i", id); wsprintfW(name, L"Button %i", id);
} else if (type & AXIS) { }
else if (type & AXIS)
{
wsprintfW(name, L"Axis %i", id); wsprintfW(name, L"Axis %i", id);
} else if (type & POV) { }
else if (type & POV)
{
wsprintfW(name, L"POV %i", id); wsprintfW(name, L"POV %i", id);
} else { }
else
{
wcscpy(name, L"Unknown"); wcscpy(name, L"Unknown");
} }
return name; return name;
@ -348,13 +395,15 @@ wchar_t *Device::GetVirtualControlName(VirtualControl *control)
{ {
static wchar_t temp[100]; static wchar_t temp[100];
wchar_t* baseName = 0; wchar_t* baseName = 0;
if (control->physicalControlIndex >= 0) { if (control->physicalControlIndex >= 0)
{
baseName = physicalControls[control->physicalControlIndex].name; baseName = physicalControls[control->physicalControlIndex].name;
if (!baseName) if (!baseName)
baseName = GetPhysicalControlName(&physicalControls[control->physicalControlIndex]); baseName = GetPhysicalControlName(&physicalControls[control->physicalControlIndex]);
} }
unsigned int uid = control->uid; unsigned int uid = control->uid;
if (!baseName) { if (!baseName)
{
baseName = GetDefaultControlName(uid & 0xFFFF, (uid >> 16) & 0x1F); baseName = GetDefaultControlName(uid & 0xFFFF, (uid >> 16) & 0x1F);
} }
uid &= 0xFF000000; uid &= 0xFF000000;
@ -363,21 +412,33 @@ wchar_t *Device::GetVirtualControlName(VirtualControl *control)
len = 99; len = 99;
memcpy(temp, baseName, len * sizeof(wchar_t)); memcpy(temp, baseName, len * sizeof(wchar_t));
temp[len] = 0; temp[len] = 0;
if (uid) { if (uid)
{
if (len > 95) if (len > 95)
len = 95; len = 95;
wchar_t* out = temp + len; wchar_t* out = temp + len;
if (uid == UID_AXIS_POS) { if (uid == UID_AXIS_POS)
{
wcscpy(out, L" +"); wcscpy(out, L" +");
} else if (uid == UID_AXIS_NEG) { }
else if (uid == UID_AXIS_NEG)
{
wcscpy(out, L" -"); wcscpy(out, L" -");
} else if (uid == UID_POV_N) { }
else if (uid == UID_POV_N)
{
wcscpy(out, L" N"); wcscpy(out, L" N");
} else if (uid == UID_POV_E) { }
else if (uid == UID_POV_E)
{
wcscpy(out, L" E"); wcscpy(out, L" E");
} else if (uid == UID_POV_S) { }
else if (uid == UID_POV_S)
{
wcscpy(out, L" S"); wcscpy(out, L" S");
} else if (uid == UID_POV_W) { }
else if (uid == UID_POV_W)
{
wcscpy(out, L" W"); wcscpy(out, L" W");
} }
} }
@ -399,9 +460,12 @@ void InputDeviceManager::AddDevice(Device *d)
void InputDeviceManager::Update(InitInfo* info) void InputDeviceManager::Update(InitInfo* info)
{ {
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++)
if (devices[i]->enabled) { {
if (!devices[i]->active) { if (devices[i]->enabled)
{
if (!devices[i]->active)
{
if (!devices[i]->Activate(info) || !devices[i]->Update()) if (!devices[i]->Activate(info) || !devices[i]->Update())
continue; continue;
devices[i]->CalcVirtualState(); devices[i]->CalcVirtualState();
@ -415,7 +479,8 @@ void InputDeviceManager::Update(InitInfo *info)
void InputDeviceManager::PostRead() void InputDeviceManager::PostRead()
{ {
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++)
{
if (devices[i]->active) if (devices[i]->active)
devices[i]->PostRead(); devices[i]->PostRead();
} }
@ -427,38 +492,50 @@ Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, i
Update(info); Update(info);
int bestDiff = FULLY_DOWN / 2; int bestDiff = FULLY_DOWN / 2;
Device* bestDevice = 0; Device* bestDevice = 0;
for (i = 0; i < numDevices; i++) { for (i = 0; i < numDevices; i++)
if (devices[i]->active) { {
for (j = 0; j < devices[i]->numVirtualControls; j++) { if (devices[i]->active)
{
for (j = 0; j < devices[i]->numVirtualControls; j++)
{
if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j]) if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j])
continue; continue;
if (devices[i]->virtualControls[j].uid & UID_POV) if (devices[i]->virtualControls[j].uid & UID_POV)
continue; continue;
// Fix for releasing button used to click on bind button // Fix for releasing button used to click on bind button
if (!((devices[i]->virtualControls[j].uid >> 16) & (POV | RELAXIS | ABSAXIS))) { if (!((devices[i]->virtualControls[j].uid >> 16) & (POV | RELAXIS | ABSAXIS)))
if (abs(devices[i]->oldVirtualControlState[j]) > abs(devices[i]->virtualControlState[j])) { {
if (abs(devices[i]->oldVirtualControlState[j]) > abs(devices[i]->virtualControlState[j]))
{
devices[i]->oldVirtualControlState[j] = 0; devices[i]->oldVirtualControlState[j] = 0;
} }
} }
int diff = abs(devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]); int diff = abs(devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]);
// Make it require a bit more work to bind relative axes. // Make it require a bit more work to bind relative axes.
if (((devices[i]->virtualControls[j].uid >> 16) & 0xFF) == RELAXIS) { if (((devices[i]->virtualControls[j].uid >> 16) & 0xFF) == RELAXIS)
{
diff = diff / 4 + 1; diff = diff / 4 + 1;
} }
// Less pressure needed to bind DS3/SCP buttons. // Less pressure needed to bind DS3/SCP buttons.
if ((devices[i]->api == DS3 || devices[i]->api == XINPUT) && (((devices[i]->virtualControls[j].uid >> 16) & 0xFF) & BUTTON)) { if ((devices[i]->api == DS3 || devices[i]->api == XINPUT) && (((devices[i]->virtualControls[j].uid >> 16) & 0xFF) & BUTTON))
{
diff *= 4; diff *= 4;
} }
if (diff > bestDiff) { if (diff > bestDiff)
if (devices[i]->virtualControls[j].uid & UID_AXIS) { {
if (devices[i]->virtualControls[j].uid & UID_AXIS)
{
if ((((devices[i]->virtualControls[j].uid >> 16) & 0xFF) != ABSAXIS)) if ((((devices[i]->virtualControls[j].uid >> 16) & 0xFF) != ABSAXIS))
continue; continue;
// Very picky when binding entire axes. Prefer binding half-axes. // Very picky when binding entire axes. Prefer binding half-axes.
if (!((devices[i]->oldVirtualControlState[j] < FULLY_DOWN / 32 && devices[i]->virtualControlState[j] > FULLY_DOWN / 8) || if (!((devices[i]->oldVirtualControlState[j] < FULLY_DOWN / 32 && devices[i]->virtualControlState[j] > FULLY_DOWN / 8) ||
(devices[i]->oldVirtualControlState[j] > 31 * FULLY_DOWN / 32 && devices[i]->virtualControlState[j] < 7 * FULLY_DOWN / 8))) { (devices[i]->oldVirtualControlState[j] > 31 * FULLY_DOWN / 32 && devices[i]->virtualControlState[j] < 7 * FULLY_DOWN / 8)))
{
continue; continue;
} }
} else if ((((devices[i]->virtualControls[j].uid >> 16) & 0xFF) == ABSAXIS)) { }
else if ((((devices[i]->virtualControls[j].uid >> 16) & 0xFF) == ABSAXIS))
{
if (devices[i]->oldVirtualControlState[j] > 15 * FULLY_DOWN / 16) if (devices[i]->oldVirtualControlState[j] > 15 * FULLY_DOWN / 16)
continue; continue;
} }
@ -466,10 +543,14 @@ Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, i
*uid = devices[i]->virtualControls[j].uid; *uid = devices[i]->virtualControls[j].uid;
*index = j; *index = j;
bestDevice = devices[i]; bestDevice = devices[i];
if (value) { if (value)
if ((devices[i]->virtualControls[j].uid >> 16) & RELAXIS) { {
if ((devices[i]->virtualControls[j].uid >> 16) & RELAXIS)
{
*value = devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]; *value = devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j];
} else { }
else
{
*value = devices[i]->virtualControlState[j]; *value = devices[i]->virtualControlState[j];
} }
} }
@ -484,7 +565,8 @@ Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, i
void InputDeviceManager::ReleaseInput() void InputDeviceManager::ReleaseInput()
{ {
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++)
{
if (devices[i]->active) if (devices[i]->active)
devices[i]->Deactivate(); devices[i]->Deactivate();
} }
@ -492,8 +574,10 @@ void InputDeviceManager::ReleaseInput()
void InputDeviceManager::EnableDevices(DeviceType type, DeviceAPI api) void InputDeviceManager::EnableDevices(DeviceType type, DeviceAPI api)
{ {
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++)
if (devices[i]->api == api && devices[i]->type == type) { {
if (devices[i]->api == api && devices[i]->type == type)
{
EnableDevice(i); EnableDevice(i);
} }
} }
@ -501,7 +585,8 @@ void InputDeviceManager::EnableDevices(DeviceType type, DeviceAPI api)
void InputDeviceManager::DisableAllDevices() void InputDeviceManager::DisableAllDevices()
{ {
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++)
{
DisableDevice(i); DisableDevice(i);
} }
} }
@ -509,15 +594,18 @@ void InputDeviceManager::DisableAllDevices()
void InputDeviceManager::DisableDevice(int index) void InputDeviceManager::DisableDevice(int index)
{ {
devices[index]->enabled = 0; devices[index]->enabled = 0;
if (devices[index]->active) { if (devices[index]->active)
{
devices[index]->Deactivate(); devices[index]->Deactivate();
} }
} }
ForceFeedbackEffectType* Device::GetForcefeedbackEffect(wchar_t* id) ForceFeedbackEffectType* Device::GetForcefeedbackEffect(wchar_t* id)
{ {
for (int i = 0; i < numFFEffectTypes; i++) { for (int i = 0; i < numFFEffectTypes; i++)
if (!wcsicmp(id, ffEffectTypes[i].effectID)) { {
if (!wcsicmp(id, ffEffectTypes[i].effectID))
{
return &ffEffectTypes[i]; return &ffEffectTypes[i];
} }
} }
@ -526,7 +614,8 @@ ForceFeedbackEffectType *Device::GetForcefeedbackEffect(wchar_t *id)
ForceFeedbackAxis* Device::GetForceFeedbackAxis(int id) ForceFeedbackAxis* Device::GetForceFeedbackAxis(int id)
{ {
for (int i = 0; i < numFFAxes; i++) { for (int i = 0; i < numFFAxes; i++)
{
if (ffAxes[i].id == id) if (ffAxes[i].id == id)
return &ffAxes[i]; return &ffAxes[i];
} }
@ -539,16 +628,22 @@ void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices)
int* matches = (int*)malloc(sizeof(int) * numDevices); int* matches = (int*)malloc(sizeof(int) * numDevices);
int i, j, port, slot; int i, j, port, slot;
Device *old, *dev; Device *old, *dev;
for (i = 0; i < numDevices; i++) { for (i = 0; i < numDevices; i++)
{
matches[i] = -1; matches[i] = -1;
} }
for (i = 0; i < numOldDevices; i++) { for (i = 0; i < numOldDevices; i++)
{
oldMatches[i] = -2; oldMatches[i] = -2;
old = oldDevices[i]; old = oldDevices[i];
for (port = 0; port < 2; port++) { for (port = 0; port < 2; port++)
for (slot = 0; slot < 4; slot++) { {
for (int padtype = 0; padtype < numPadTypes; padtype++) { for (slot = 0; slot < 4; slot++)
if (old->pads[port][slot][padtype].numBindings + old->pads[port][slot][padtype].numFFBindings) { {
for (int padtype = 0; padtype < numPadTypes; padtype++)
{
if (old->pads[port][slot][padtype].numBindings + old->pads[port][slot][padtype].numFFBindings)
{
// Means that there are bindings. // Means that there are bindings.
oldMatches[i] = -1; oldMatches[i] = -1;
} }
@ -557,20 +652,26 @@ void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices)
} }
} }
// Loops through ids looking for match, from most specific to most general. // Loops through ids looking for match, from most specific to most general.
for (int id = 0; id < 3; id++) { for (int id = 0; id < 3; id++)
for (i = 0; i < numOldDevices; i++) { {
for (i = 0; i < numOldDevices; i++)
{
if (oldMatches[i] >= 0) if (oldMatches[i] >= 0)
continue; continue;
for (j = 0; j < numDevices; j++) { for (j = 0; j < numDevices; j++)
if (matches[j] >= 0) { {
if (matches[j] >= 0)
{
continue; continue;
} }
wchar_t* id1 = devices[j]->IDs[id]; wchar_t* id1 = devices[j]->IDs[id];
wchar_t* id2 = oldDevices[i]->IDs[id]; wchar_t* id2 = oldDevices[i]->IDs[id];
if (!id1 || !id2) { if (!id1 || !id2)
{
continue; continue;
} }
if (!wcsicmp(id1, id2)) { if (!wcsicmp(id1, id2))
{
matches[j] = i; matches[j] = i;
oldMatches[i] = j; oldMatches[i] = j;
break; break;
@ -579,23 +680,28 @@ void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices)
} }
} }
for (i = 0; i < numOldDevices; i++) { for (i = 0; i < numOldDevices; i++)
{
if (oldMatches[i] == -2) if (oldMatches[i] == -2)
continue; continue;
old = oldDevices[i]; old = oldDevices[i];
if (oldMatches[i] < 0) { if (oldMatches[i] < 0)
{
dev = new Device(old->api, old->type, old->displayName, old->instanceID, old->productID); dev = new Device(old->api, old->type, old->displayName, old->instanceID, old->productID);
dev->attached = 0; dev->attached = 0;
AddDevice(dev); AddDevice(dev);
for (j = 0; j < old->numVirtualControls; j++) { for (j = 0; j < old->numVirtualControls; j++)
{
VirtualControl* c = old->virtualControls + j; VirtualControl* c = old->virtualControls + j;
dev->AddVirtualControl(c->uid, -1); dev->AddVirtualControl(c->uid, -1);
} }
for (j = 0; j < old->numFFEffectTypes; j++) { for (j = 0; j < old->numFFEffectTypes; j++)
{
ForceFeedbackEffectType* effect = old->ffEffectTypes + j; ForceFeedbackEffectType* effect = old->ffEffectTypes + j;
dev->AddFFEffectType(effect->displayName, effect->effectID, effect->type); dev->AddFFEffectType(effect->displayName, effect->effectID, effect->type);
} }
for (j = 0; j < old->numFFAxes; j++) { for (j = 0; j < old->numFFAxes; j++)
{
ForceFeedbackAxis* axis = old->ffAxes + j; ForceFeedbackAxis* axis = old->ffAxes + j;
dev->AddFFAxis(axis->displayName, axis->id); dev->AddFFAxis(axis->displayName, axis->id);
} }
@ -603,37 +709,50 @@ void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices)
// Indices will be the same. // Indices will be the same.
memcpy(dev->pads, old->pads, sizeof(old->pads)); memcpy(dev->pads, old->pads, sizeof(old->pads));
memset(old->pads, 0, sizeof(old->pads)); memset(old->pads, 0, sizeof(old->pads));
} else { }
else
{
dev = devices[oldMatches[i]]; dev = devices[oldMatches[i]];
for (port = 0; port < 2; port++) { for (port = 0; port < 2; port++)
for (slot = 0; slot < 4; slot++) { {
for (int padtype = 0; padtype < numPadTypes; padtype++) { for (slot = 0; slot < 4; slot++)
if (old->pads[port][slot][padtype].numBindings) { {
for (int padtype = 0; padtype < numPadTypes; padtype++)
{
if (old->pads[port][slot][padtype].numBindings)
{
dev->pads[port][slot][padtype].bindings = (Binding*)malloc(old->pads[port][slot][padtype].numBindings * sizeof(Binding)); dev->pads[port][slot][padtype].bindings = (Binding*)malloc(old->pads[port][slot][padtype].numBindings * sizeof(Binding));
for (int j = 0; j < old->pads[port][slot][padtype].numBindings; j++) { for (int j = 0; j < old->pads[port][slot][padtype].numBindings; j++)
{
Binding* bo = old->pads[port][slot][padtype].bindings + j; Binding* bo = old->pads[port][slot][padtype].bindings + j;
Binding* bn = dev->pads[port][slot][padtype].bindings + dev->pads[port][slot][padtype].numBindings; Binding* bn = dev->pads[port][slot][padtype].bindings + dev->pads[port][slot][padtype].numBindings;
VirtualControl* cn = dev->GetVirtualControl(old->virtualControls[bo->controlIndex].uid); VirtualControl* cn = dev->GetVirtualControl(old->virtualControls[bo->controlIndex].uid);
if (cn) { if (cn)
{
*bn = *bo; *bn = *bo;
bn->controlIndex = cn - dev->virtualControls; bn->controlIndex = cn - dev->virtualControls;
dev->pads[port][slot][padtype].numBindings++; dev->pads[port][slot][padtype].numBindings++;
} }
} }
} }
if (old->pads[port][slot][padtype].numFFBindings) { if (old->pads[port][slot][padtype].numFFBindings)
{
dev->pads[port][slot][padtype].ffBindings = (ForceFeedbackBinding*)malloc(old->pads[port][slot][padtype].numFFBindings * sizeof(ForceFeedbackBinding)); dev->pads[port][slot][padtype].ffBindings = (ForceFeedbackBinding*)malloc(old->pads[port][slot][padtype].numFFBindings * sizeof(ForceFeedbackBinding));
for (int j = 0; j < old->pads[port][slot][padtype].numFFBindings; j++) { for (int j = 0; j < old->pads[port][slot][padtype].numFFBindings; j++)
{
ForceFeedbackBinding* bo = old->pads[port][slot][padtype].ffBindings + j; ForceFeedbackBinding* bo = old->pads[port][slot][padtype].ffBindings + j;
ForceFeedbackBinding* bn = dev->pads[port][slot][padtype].ffBindings + dev->pads[port][slot][padtype].numFFBindings; ForceFeedbackBinding* bn = dev->pads[port][slot][padtype].ffBindings + dev->pads[port][slot][padtype].numFFBindings;
ForceFeedbackEffectType* en = dev->GetForcefeedbackEffect(old->ffEffectTypes[bo->effectIndex].effectID); ForceFeedbackEffectType* en = dev->GetForcefeedbackEffect(old->ffEffectTypes[bo->effectIndex].effectID);
if (en) { if (en)
{
*bn = *bo; *bn = *bo;
bn->effectIndex = en - dev->ffEffectTypes; bn->effectIndex = en - dev->ffEffectTypes;
bn->axes = (AxisEffectInfo*)calloc(dev->numFFAxes, sizeof(AxisEffectInfo)); bn->axes = (AxisEffectInfo*)calloc(dev->numFFAxes, sizeof(AxisEffectInfo));
for (int k = 0; k < old->numFFAxes; k++) { for (int k = 0; k < old->numFFAxes; k++)
{
ForceFeedbackAxis* newAxis = dev->GetForceFeedbackAxis(old->ffAxes[k].id); ForceFeedbackAxis* newAxis = dev->GetForceFeedbackAxis(old->ffAxes[k].id);
if (newAxis) { if (newAxis)
{
bn->axes[newAxis - dev->ffAxes] = bo->axes[k]; bn->axes[newAxis - dev->ffAxes] = bo->axes[k];
} }
} }
@ -652,9 +771,11 @@ void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices)
void InputDeviceManager::SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) void InputDeviceManager::SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force)
{ {
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++)
{
Device* dev = devices[i]; Device* dev = devices[i];
if (dev->enabled && dev->numFFEffectTypes) { if (dev->enabled && dev->numFFEffectTypes)
{
dev->SetEffects(port, slot, motor, force); dev->SetEffects(port, slot, motor, force);
} }
} }

View File

@ -31,7 +31,8 @@
* Still more effort than it's worth to port to Linux, however. * Still more effort than it's worth to port to Linux, however.
*/ */
enum PadType { enum PadType
{
DisabledPad, DisabledPad,
Dualshock2Pad, Dualshock2Pad,
GuitarPad, GuitarPad,
@ -44,7 +45,8 @@ enum PadType {
// Mostly match DirectInput8 values. Note that these are for physical controls. // 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 // One physical axis maps to 3 virtual ones, and one physical POV control maps to
// 4 virtual ones. // 4 virtual ones.
enum ControlType { enum ControlType
{
NO_CONTROL = 0, NO_CONTROL = 0,
// Axes are ints. Relative axes are for mice, mice wheels, etc, // Axes are ints. Relative axes are for mice, mice wheels, etc,
// and are always reported relative to their last value. // and are always reported relative to their last value.
@ -130,7 +132,8 @@ struct PhysicalControl
wchar_t* name; wchar_t* name;
}; };
enum DeviceAPI { enum DeviceAPI
{
NO_API = 0, NO_API = 0,
DI = 1, DI = 1,
WM = 2, WM = 2,
@ -148,14 +151,16 @@ enum DeviceAPI {
LNX_JOY = 17, LNX_JOY = 17,
}; };
enum DeviceType { enum DeviceType
{
NO_DEVICE = 0, NO_DEVICE = 0,
KEYBOARD = 1, KEYBOARD = 1,
MOUSE = 2, MOUSE = 2,
OTHER = 3 OTHER = 3
}; };
enum EffectType { enum EffectType
{
EFFECT_CONSTANT, EFFECT_CONSTANT,
EFFECT_PERIODIC, EFFECT_PERIODIC,
EFFECT_RAMP EFFECT_RAMP

View File

@ -36,7 +36,8 @@ static keyEvent queuedEvents[EVENT_QUEUE_LEN];
void QueueKeyEvent(int key, int event) void QueueKeyEvent(int key, int event)
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
if (!csInitialized) { if (!csInitialized)
{
csInitialized = 1; csInitialized = 1;
InitializeCriticalSection(&cSection); InitializeCriticalSection(&cSection);
} }
@ -49,10 +50,12 @@ void QueueKeyEvent(int key, int event)
// purposes when a game is killing the emulator for whatever reason. // purposes when a game is killing the emulator for whatever reason.
if (nextQueuedEvent == lastQueuedEvent || if (nextQueuedEvent == lastQueuedEvent ||
queuedEvents[nextQueuedEvent].key != VK_ESCAPE || queuedEvents[nextQueuedEvent].key != VK_ESCAPE ||
queuedEvents[nextQueuedEvent].evt != KEYPRESS) { queuedEvents[nextQueuedEvent].evt != KEYPRESS)
{
// Clear queue on escape down, bringing escape to front. May do something // Clear queue on escape down, bringing escape to front. May do something
// with shift/ctrl/alt and F-keys, later. // with shift/ctrl/alt and F-keys, later.
if (event == KEYPRESS && key == VK_ESCAPE) { if (event == KEYPRESS && key == VK_ESCAPE)
{
nextQueuedEvent = lastQueuedEvent; nextQueuedEvent = lastQueuedEvent;
} }
@ -61,7 +64,8 @@ void QueueKeyEvent(int key, int event)
lastQueuedEvent = (lastQueuedEvent + 1) % EVENT_QUEUE_LEN; lastQueuedEvent = (lastQueuedEvent + 1) % EVENT_QUEUE_LEN;
// If queue wrapped around, remove last element. // If queue wrapped around, remove last element.
if (nextQueuedEvent == lastQueuedEvent) { if (nextQueuedEvent == lastQueuedEvent)
{
nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN; nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN;
} }
} }
@ -92,7 +96,8 @@ void ClearKeyQueue()
{ {
lastQueuedEvent = nextQueuedEvent; lastQueuedEvent = nextQueuedEvent;
#ifdef _MSC_VER #ifdef _MSC_VER
if (csInitialized) { if (csInitialized)
{
DeleteCriticalSection(&cSection); DeleteCriticalSection(&cSection);
csInitialized = 0; csInitialized = 0;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -93,11 +93,13 @@ public:
hWndProc = initInfo->hWndProc; hWndProc = initInfo->hWndProc;
active = 1; active = 1;
if (!rawKeyboardActivatedCount++) { if (!rawKeyboardActivatedCount++)
{
if (!rawMouseActivatedCount) if (!rawMouseActivatedCount)
hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
if (!GetRawKeyboards(hWndProc->hWndEaten)) { if (!GetRawKeyboards(hWndProc->hWndEaten))
{
Deactivate(); Deactivate();
return 0; return 0;
} }
@ -110,10 +112,12 @@ public:
void Deactivate() void Deactivate()
{ {
FreeState(); FreeState();
if (active) { if (active)
{
active = 0; active = 0;
rawKeyboardActivatedCount--; rawKeyboardActivatedCount--;
if (!rawKeyboardActivatedCount) { if (!rawKeyboardActivatedCount)
{
ReleaseRawKeyboards(); ReleaseRawKeyboards();
if (!rawMouseActivatedCount) if (!rawMouseActivatedCount)
hWndProc->ReleaseExtraProc(RawInputWndProc); hWndProc->ReleaseExtraProc(RawInputWndProc);
@ -144,12 +148,14 @@ public:
// Have to be careful with order. At worst, one unmatched call to ReleaseRawMice on // Have to be careful with order. At worst, one unmatched call to ReleaseRawMice on
// EatWndProc fail. In all other cases, no unmatched initialization/cleanup // EatWndProc fail. In all other cases, no unmatched initialization/cleanup
// lines. // lines.
if (!rawMouseActivatedCount++) { if (!rawMouseActivatedCount++)
{
GetMouseCapture(hWndProc->hWndEaten); GetMouseCapture(hWndProc->hWndEaten);
if (!rawKeyboardActivatedCount) if (!rawKeyboardActivatedCount)
hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
if (!GetRawMice(hWndProc->hWndEaten)) { if (!GetRawMice(hWndProc->hWndEaten))
{
Deactivate(); Deactivate();
return 0; return 0;
} }
@ -162,13 +168,16 @@ public:
void Deactivate() void Deactivate()
{ {
FreeState(); FreeState();
if (active) { if (active)
{
active = 0; active = 0;
rawMouseActivatedCount--; rawMouseActivatedCount--;
if (!rawMouseActivatedCount) { if (!rawMouseActivatedCount)
{
ReleaseRawMice(); ReleaseRawMice();
ReleaseMouseCapture(); ReleaseMouseCapture();
if (!rawKeyboardActivatedCount) { if (!rawKeyboardActivatedCount)
{
hWndProc->ReleaseExtraProc(RawInputWndProc); hWndProc->ReleaseExtraProc(RawInputWndProc);
} }
} }
@ -178,16 +187,21 @@ public:
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 (uMsg == WM_INPUT)
if (GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT) { {
if (GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT)
{
RAWINPUT in; RAWINPUT in;
unsigned int size = sizeof(RAWINPUT); unsigned int size = sizeof(RAWINPUT);
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &in, &size, sizeof(RAWINPUTHEADER)) > 0) { if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &in, &size, sizeof(RAWINPUTHEADER)) > 0)
for (int i = 0; i < dm->numDevices; i++) { {
for (int i = 0; i < dm->numDevices; i++)
{
Device* dev = dm->devices[i]; Device* dev = dm->devices[i];
if (dev->api != RAW || !dev->active) if (dev->api != RAW || !dev->active)
continue; continue;
if (in.header.dwType == RIM_TYPEKEYBOARD && dev->type == KEYBOARD) { if (in.header.dwType == RIM_TYPEKEYBOARD && dev->type == KEYBOARD)
{
RawInputKeyboard* rik = (RawInputKeyboard*)dev; RawInputKeyboard* rik = (RawInputKeyboard*)dev;
if (rik->hDevice != in.header.hDevice) if (rik->hDevice != in.header.hDevice)
continue; continue;
@ -195,11 +209,14 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
u32 uMsg = in.data.keyboard.Message; u32 uMsg = in.data.keyboard.Message;
if (!(in.data.keyboard.VKey >> 8)) if (!(in.data.keyboard.VKey >> 8))
rik->UpdateKey((u8)in.data.keyboard.VKey, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)); rik->UpdateKey((u8)in.data.keyboard.VKey, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
} else if (in.header.dwType == RIM_TYPEMOUSE && dev->type == MOUSE) { }
else if (in.header.dwType == RIM_TYPEMOUSE && dev->type == MOUSE)
{
RawInputMouse* rim = (RawInputMouse*)dev; RawInputMouse* rim = (RawInputMouse*)dev;
if (rim->hDevice != in.header.hDevice) if (rim->hDevice != in.header.hDevice)
continue; continue;
if (in.data.mouse.usFlags) { if (in.data.mouse.usFlags)
{
// Never been set for me, and specs on what most of them // Never been set for me, and specs on what most of them
// actually mean is sorely lacking. Also, specs erroneously // actually mean is sorely lacking. Also, specs erroneously
// indicate MOUSE_MOVE_RELATIVE is a flag, when it's really // indicate MOUSE_MOVE_RELATIVE is a flag, when it's really
@ -209,18 +226,22 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
unsigned short buttons = in.data.mouse.usButtonFlags & 0x3FF; unsigned short buttons = in.data.mouse.usButtonFlags & 0x3FF;
int button = 0; int button = 0;
while (buttons) { while (buttons)
if (buttons & 3) { {
if (buttons & 3)
{
// 2 is up, 1 is down. Up takes precedence over down. // 2 is up, 1 is down. Up takes precedence over down.
rim->UpdateButton(button, !(buttons & 2)); rim->UpdateButton(button, !(buttons & 2));
} }
button++; button++;
buttons >>= 2; buttons >>= 2;
} }
if (in.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { if (in.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
{
rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData) / WHEEL_DELTA); rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData) / WHEEL_DELTA);
} }
if (in.data.mouse.lLastX || in.data.mouse.lLastY) { if (in.data.mouse.lLastX || in.data.mouse.lLastY)
{
rim->UpdateAxis(0, in.data.mouse.lLastX); rim->UpdateAxis(0, in.data.mouse.lLastX);
rim->UpdateAxis(1, in.data.mouse.lLastY); rim->UpdateAxis(1, in.data.mouse.lLastY);
} }
@ -228,14 +249,19 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
} }
} }
} }
} else if (uMsg == WM_ACTIVATE) { }
for (int i = 0; i < dm->numDevices; i++) { else if (uMsg == WM_ACTIVATE)
{
for (int i = 0; i < dm->numDevices; i++)
{
Device* dev = dm->devices[i]; Device* dev = dm->devices[i];
if (dev->api != RAW || dev->physicalControlState == 0) if (dev->api != RAW || dev->physicalControlState == 0)
continue; continue;
memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls); memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls);
} }
} else if (uMsg == WM_SIZE && rawMouseActivatedCount) { }
else if (uMsg == WM_SIZE && rawMouseActivatedCount)
{
// Doesn't really matter for raw mice, as I disable legacy stuff, but shouldn't hurt. // Doesn't really matter for raw mice, as I disable legacy stuff, but shouldn't hurt.
WindowsMouse::WindowResized(hWnd); WindowsMouse::WindowResized(hWnd);
} }
@ -246,7 +272,8 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
void EnumRawInputDevices() void EnumRawInputDevices()
{ {
int count = 0; int count = 0;
if (GetRawInputDeviceList(0, (unsigned int *)&count, sizeof(RAWINPUTDEVICELIST)) != (UINT)-1 && 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* instanceID = (wchar_t*)malloc(41000 * sizeof(wchar_t));
wchar_t* keyName = instanceID + 11000; wchar_t* keyName = instanceID + 11000;
wchar_t* displayName = keyName + 10000; wchar_t* displayName = keyName + 10000;
@ -258,14 +285,17 @@ void EnumRawInputDevices()
count = GetRawInputDeviceList(list, (unsigned int*)&count, sizeof(RAWINPUTDEVICELIST)); count = GetRawInputDeviceList(list, (unsigned int*)&count, sizeof(RAWINPUTDEVICELIST));
// Not necessary, but reminder that count is -1 on failure. // Not necessary, but reminder that count is -1 on failure.
if (count > 0) { if (count > 0)
for (int i = 0; i < count; i++) { {
for (int i = 0; i < count; i++)
{
if (list[i].dwType != RIM_TYPEKEYBOARD && list[i].dwType != RIM_TYPEMOUSE) if (list[i].dwType != RIM_TYPEKEYBOARD && list[i].dwType != RIM_TYPEMOUSE)
continue; continue;
UINT bufferLen = 10000; UINT bufferLen = 10000;
int nameLen = GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, instanceID, &bufferLen); int nameLen = GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, instanceID, &bufferLen);
if (nameLen >= 4) { if (nameLen >= 4)
{
// nameLen includes terminating null. // nameLen includes terminating null.
nameLen--; nameLen--;
@ -273,12 +303,14 @@ void EnumRawInputDevices()
// and reformat it to point to registry entry containing device description. // and reformat it to point to registry entry containing device description.
wcscpy(productID, instanceID); wcscpy(productID, instanceID);
wchar_t* temp = 0; wchar_t* temp = 0;
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++)
{
wchar_t* s = wcschr(productID, '#'); wchar_t* s = wcschr(productID, '#');
if (!s) if (!s)
break; break;
*s = '\\'; *s = '\\';
if (j == 2) { if (j == 2)
{
*s = 0; *s = 0;
} }
if (j == 1) if (j == 1)
@ -290,11 +322,13 @@ void EnumRawInputDevices()
*temp = 0; *temp = 0;
int haveDescription = 0; int haveDescription = 0;
HKEY hKey; HKEY hKey;
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey)) { if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey))
{
DWORD type; DWORD type;
DWORD len = 10000 * sizeof(wchar_t); DWORD len = 10000 * sizeof(wchar_t);
if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"DeviceDesc", 0, &type, (BYTE*)displayName, &len) && if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"DeviceDesc", 0, &type, (BYTE*)displayName, &len) &&
len && type == REG_SZ) { len && type == REG_SZ)
{
wchar_t* temp2 = wcsrchr(displayName, ';'); wchar_t* temp2 = wcsrchr(displayName, ';');
if (!temp2) if (!temp2)
temp2 = displayName; temp2 = displayName;
@ -306,13 +340,16 @@ void EnumRawInputDevices()
} }
RegCloseKey(hKey); RegCloseKey(hKey);
} }
if (list[i].dwType == RIM_TYPEKEYBOARD) { if (list[i].dwType == RIM_TYPEKEYBOARD)
{
if (!haveDescription) if (!haveDescription)
wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++); wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++);
else else
wsprintfW(displayName, L"Raw KB: %s", keyName); wsprintfW(displayName, L"Raw KB: %s", keyName);
dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID)); dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID));
} else if (list[i].dwType == RIM_TYPEMOUSE) { }
else if (list[i].dwType == RIM_TYPEMOUSE)
{
if (!haveDescription) if (!haveDescription)
wsprintfW(displayName, L"Raw Mouse %i", mouseCount++); wsprintfW(displayName, L"Raw Mouse %i", mouseCount++);
else else

View File

@ -21,7 +21,8 @@ LPWSTR dialog_message(int ID, bool *updateText)
{ {
if (updateText) if (updateText)
*updateText = true; *updateText = true;
switch (ID) { switch (ID)
{
// General tab // General tab
case IDC_M_WM: case IDC_M_WM:
case IDC_M_RAW: case IDC_M_RAW:

View File

@ -21,7 +21,8 @@ wchar_t *GetVKStringW(unsigned char vk)
{ {
int flag; int flag;
static wchar_t t[20]; static wchar_t t[20];
switch (vk) { switch (vk)
{
case 0x0C: case 0x0C:
return L"Clear"; return L"Clear";
case 0x13: case 0x13:
@ -97,10 +98,13 @@ wchar_t *GetVKStringW(unsigned char vk)
break; break;
} }
int res = MapVirtualKey(vk, MAPVK_VK_TO_VSC); int res = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
if (res && GetKeyNameText((res << 16) | flag, t, 20)) { if (res && GetKeyNameText((res << 16) | flag, t, 20))
{
// don't trust windows // don't trust windows
t[19] = 0; t[19] = 0;
} else { }
else
{
wsprintfW(t, L"Key %i", vk); wsprintfW(t, L"Key %i", vk);
} }
return t; return t;

View File

@ -23,7 +23,8 @@
WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t* displayName, wchar_t* instanceID, wchar_t* deviceID) WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t* displayName, wchar_t* instanceID, wchar_t* deviceID)
: Device(api, KEYBOARD, displayName, instanceID, deviceID) : Device(api, KEYBOARD, displayName, instanceID, deviceID)
{ {
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++)
{
AddPhysicalControl(PSHBTN, i, i); AddPhysicalControl(PSHBTN, i, i);
} }
} }
@ -31,7 +32,8 @@ WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *i
wchar_t* WindowsKeyboard::GetPhysicalControlName(PhysicalControl* control) wchar_t* WindowsKeyboard::GetPhysicalControlName(PhysicalControl* control)
{ {
int id = control->id; int id = control->id;
if (control->type == PSHBTN && id >= 0 && id < 256) { if (control->type == PSHBTN && id >= 0 && id < 256)
{
wchar_t* w = GetVKStringW(id); wchar_t* w = GetVKStringW(id);
if (w) if (w)
return w; return w;
@ -41,11 +43,14 @@ wchar_t *WindowsKeyboard::GetPhysicalControlName(PhysicalControl *control)
void WindowsKeyboard::UpdateKey(int vkey, int state) void WindowsKeyboard::UpdateKey(int vkey, int state)
{ {
if (vkey > 7 && vkey < 256) { if (vkey > 7 && vkey < 256)
{
int newState = state * FULLY_DOWN; int newState = state * FULLY_DOWN;
if (newState != physicalControlState[vkey]) { if (newState != physicalControlState[vkey])
{
// Check for alt-F4 to avoid toggling skip mode incorrectly. // Check for alt-F4 to avoid toggling skip mode incorrectly.
if (vkey != VK_F4 || !(physicalControlState[VK_MENU] || physicalControlState[VK_RMENU] || physicalControlState[VK_LMENU])) { if (vkey != VK_F4 || !(physicalControlState[VK_MENU] || physicalControlState[VK_RMENU] || physicalControlState[VK_LMENU]))
{
int event = KEYPRESS; int event = KEYPRESS;
if (!newState) if (!newState)
event = KEYRELEASE; event = KEYRELEASE;
@ -59,10 +64,12 @@ void WindowsKeyboard::UpdateKey(int vkey, int state)
void WindowsKeyboard::InitState() void WindowsKeyboard::InitState()
{ {
AllocState(); AllocState();
for (int vkey = 5; vkey < 256; vkey++) { for (int vkey = 5; vkey < 256; vkey++)
{
int value = (unsigned short)(((short)GetAsyncKeyState(vkey)) >> 15); int value = (unsigned short)(((short)GetAsyncKeyState(vkey)) >> 15);
value += value & 1; value += value & 1;
if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT) { if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT)
{
value = 0; value = 0;
} }
physicalControlState[vkey] = value; physicalControlState[vkey] = value;

View File

@ -60,7 +60,8 @@ public:
void Deactivate() void Deactivate()
{ {
if (active) { if (active)
{
if (!wmm) if (!wmm)
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
wmk = 0; wmk = 0;
@ -107,7 +108,8 @@ public:
void Deactivate() void Deactivate()
{ {
if (active) { if (active)
{
if (!wmk) if (!wmk)
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
ReleaseMouseCapture(); ReleaseMouseCapture();
@ -120,60 +122,88 @@ public:
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 (wmk)
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) { {
if (wParam == VK_SHIFT) { if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP)
{
if (wParam == VK_SHIFT)
{
wmk->CheckKey(VK_RSHIFT); wmk->CheckKey(VK_RSHIFT);
wmk->CheckKey(VK_LSHIFT); wmk->CheckKey(VK_LSHIFT);
} else if (wParam == VK_CONTROL) { }
else if (wParam == VK_CONTROL)
{
wmk->CheckKey(VK_RCONTROL); wmk->CheckKey(VK_RCONTROL);
wmk->CheckKey(VK_LCONTROL); wmk->CheckKey(VK_LCONTROL);
} else if (wParam == VK_MENU) { }
else if (wParam == VK_MENU)
{
wmk->CheckKey(VK_RMENU); wmk->CheckKey(VK_RMENU);
wmk->CheckKey(VK_LMENU); wmk->CheckKey(VK_LMENU);
} else }
else
wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)); wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
return NO_WND_PROC; return NO_WND_PROC;
} }
// Needed to prevent default handling of keys in some situations. // Needed to prevent default handling of keys in some situations.
else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR) { else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR)
{
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_ACTIVATE) { }
else if (uMsg == WM_ACTIVATE)
{
// Not really needed, but doesn't hurt. // Not really needed, but doesn't hurt.
memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls); memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls);
} }
} }
if (wmm) { if (wmm)
if (uMsg == WM_MOUSEMOVE) { {
if (uMsg == WM_MOUSEMOVE)
{
POINT p; POINT p;
GetCursorPos(&p); GetCursorPos(&p);
// Need check to prevent cursor movement cascade. // Need check to prevent cursor movement cascade.
if (p.x != wmm->center.x || p.y != wmm->center.y) { if (p.x != wmm->center.x || p.y != wmm->center.y)
{
wmm->UpdateAxis(0, p.x - wmm->center.x); wmm->UpdateAxis(0, p.x - wmm->center.x);
wmm->UpdateAxis(1, p.y - wmm->center.y); wmm->UpdateAxis(1, p.y - wmm->center.y);
SetCursorPos(wmm->center.x, wmm->center.y); SetCursorPos(wmm->center.x, wmm->center.y);
} }
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) { }
else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
{
wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN); wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN);
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) { }
else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP)
{
wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN); wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN);
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) { }
else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
{
wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN); wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN);
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) { }
else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
{
wmm->UpdateButton(3 + ((wParam >> 16) == XBUTTON2), uMsg == WM_XBUTTONDOWN); wmm->UpdateButton(3 + ((wParam >> 16) == XBUTTON2), uMsg == WM_XBUTTONDOWN);
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_MOUSEWHEEL) { }
else if (uMsg == WM_MOUSEWHEEL)
{
wmm->UpdateAxis(2, ((int)wParam >> 16) / WHEEL_DELTA); wmm->UpdateAxis(2, ((int)wParam >> 16) / WHEEL_DELTA);
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_MOUSEHWHEEL) { }
else if (uMsg == WM_MOUSEHWHEEL)
{
wmm->UpdateAxis(3, ((int)wParam >> 16) / WHEEL_DELTA); wmm->UpdateAxis(3, ((int)wParam >> 16) / WHEEL_DELTA);
return NO_WND_PROC; return NO_WND_PROC;
} else if (uMsg == WM_SIZE && wmm->active) { }
else if (uMsg == WM_SIZE && wmm->active)
{
WindowsMouse::WindowResized(hWnd); WindowsMouse::WindowResized(hWnd);
} }
// Taken care of elsewhere. When binding, killing focus means stop reading input. // Taken care of elsewhere. When binding, killing focus means stop reading input.

View File

@ -26,11 +26,13 @@ WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wcha
: Device(api, MOUSE, displayName, instanceID, deviceID) : Device(api, MOUSE, displayName, instanceID, deviceID)
{ {
int i; int i;
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++)
{
AddPhysicalControl(PSHBTN, i, i); AddPhysicalControl(PSHBTN, i, i);
} }
for (i = 0; i < 3 + hWheel; i++) { for (i = 0; i < 3 + hWheel; i++)
{
AddPhysicalControl(RELAXIS, i + 5, i + 5); AddPhysicalControl(RELAXIS, i + 5, i + 5);
} }
} }

View File

@ -30,7 +30,8 @@ WndProcEater::WndProcEater()
WndProcEater::~WndProcEater() throw() WndProcEater::~WndProcEater() throw()
{ {
if (hMutex) { if (hMutex)
{
ReleaseMutex(hMutex); ReleaseMutex(hMutex);
CloseHandle(hMutex); CloseHandle(hMutex);
} }
@ -44,13 +45,16 @@ void WndProcEater::ReleaseExtraProc(ExtraWndProc proc)
//printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc ); //printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc );
for (int i = 0; i < numExtraProcs; i++) { for (int i = 0; i < numExtraProcs; i++)
if (extraProcs[i].proc == proc) { {
if (extraProcs[i].proc == proc)
{
extraProcs[i] = extraProcs[--numExtraProcs]; extraProcs[i] = extraProcs[--numExtraProcs];
break; break;
} }
} }
if (!numExtraProcs && eatenWndProc) { if (!numExtraProcs && eatenWndProc)
{
free(extraProcs); free(extraProcs);
extraProcs = 0; extraProcs = 0;
// As numExtraProcs is 0, won't cause recursion if called from Release(). // As numExtraProcs is 0, won't cause recursion if called from Release().
@ -62,7 +66,8 @@ void WndProcEater::Release()
{ {
while (numExtraProcs) while (numExtraProcs)
ReleaseExtraProc(extraProcs[0].proc); ReleaseExtraProc(extraProcs[0].proc);
if (hWndEaten && IsWindow(hWndEaten)) { if (hWndEaten && IsWindow(hWndEaten))
{
RemoveProp(hWndEaten, L"LilyHaxxor"); RemoveProp(hWndEaten, L"LilyHaxxor");
SetWindowLongPtr(hWndEaten, GWLP_WNDPROC, (LONG_PTR)eatenWndProc); SetWindowLongPtr(hWndEaten, GWLP_WNDPROC, (LONG_PTR)eatenWndProc);
hWndEaten = 0; hWndEaten = 0;
@ -78,28 +83,35 @@ LRESULT WndProcEater::_OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
ExtraWndProcResult res = CONTINUE_BLISSFULLY; ExtraWndProcResult res = CONTINUE_BLISSFULLY;
LRESULT out = 0; LRESULT out = 0;
// Here because want it for binding, even when no keyboard mode is selected. // Here because want it for binding, even when no keyboard mode is selected.
if (uMsg == WM_GETDLGCODE) { if (uMsg == WM_GETDLGCODE)
{
return DLGC_WANTALLKEYS | CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam); return DLGC_WANTALLKEYS | CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
} }
for (int i = 0; i < numExtraProcs; i++) { for (int i = 0; i < numExtraProcs; i++)
{
// Note: Second bit of deviceUpdateQueued is only set when I receive a device change // 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 // 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. // 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; // if ((deviceUpdateQueued&2) && (extraProcs[i].flags & EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) continue;
ExtraWndProcResult res2 = extraProcs[i].proc(hWnd, uMsg, wParam, lParam, &out); ExtraWndProcResult res2 = extraProcs[i].proc(hWnd, uMsg, wParam, lParam, &out);
if (res2 != res) { if (res2 != res)
if (res2 == CONTINUE_BLISSFULLY_AND_RELEASE_PROC) { {
if (res2 == CONTINUE_BLISSFULLY_AND_RELEASE_PROC)
{
ReleaseExtraProc(extraProcs[i].proc); ReleaseExtraProc(extraProcs[i].proc);
i--; i--;
} else if (res2 > res) }
else if (res2 > res)
res = res2; res = res2;
} }
} }
if (res != NO_WND_PROC) { if (res != NO_WND_PROC)
if (out == WM_DESTROY) { {
if (out == WM_DESTROY)
{
Release(); Release();
} }
if (res == CONTINUE_BLISSFULLY) if (res == CONTINUE_BLISSFULLY)

View File

@ -17,7 +17,8 @@
/* Need this to let window be subclassed multiple times but still clean up nicely. /* Need this to let window be subclassed multiple times but still clean up nicely.
*/ */
enum ExtraWndProcResult { enum ExtraWndProcResult
{
CONTINUE_BLISSFULLY, CONTINUE_BLISSFULLY,
// Calls ReleaseExtraProc without messing up order. // Calls ReleaseExtraProc without messing up order.
CONTINUE_BLISSFULLY_AND_RELEASE_PROC, CONTINUE_BLISSFULLY_AND_RELEASE_PROC,

View File

@ -101,10 +101,12 @@ public:
memset(&xInputVibration, 0, sizeof(xInputVibration)); memset(&xInputVibration, 0, sizeof(xInputVibration));
this->index = index; this->index = index;
int i; int i;
for (i = 0; i < 17; i++) { // Skip empty bit for (i = 0; i < 17; i++)
{ // Skip empty bit
AddPhysicalControl(PRESSURE_BTN, i + (i > 10), 0); AddPhysicalControl(PRESSURE_BTN, i + (i > 10), 0);
} }
for (; i < 21; i++) { for (; i < 21; i++)
{
AddPhysicalControl(ABSAXIS, i + 2, 0); AddPhysicalControl(ABSAXIS, i + 2, 0);
} }
AddFFAxis(L"Slow Motor", 0); AddFFAxis(L"Slow Motor", 0);
@ -138,7 +140,8 @@ public:
L"Right Thumb Y", L"Right Thumb Y",
}; };
unsigned int i = (unsigned int)(c - physicalControls); unsigned int i = (unsigned int)(c - physicalControls);
if (i < 21) { if (i < 21)
{
return (wchar_t*)names[i]; return (wchar_t*)names[i];
} }
return Device::GetPhysicalControlName(c); return Device::GetPhysicalControlName(c);
@ -148,7 +151,8 @@ public:
{ {
if (active) if (active)
Deactivate(); Deactivate();
if (!xInputActiveCount) { if (!xInputActiveCount)
{
pXInputEnable(1); pXInputEnable(1);
} }
xInputActiveCount++; xInputActiveCount++;
@ -162,15 +166,18 @@ public:
if (!active) if (!active)
return 0; return 0;
SCP_EXTN pressure; SCP_EXTN pressure;
if (!pXInputGetExtended || (ERROR_SUCCESS != pXInputGetExtended(index, &pressure))) { if (!pXInputGetExtended || (ERROR_SUCCESS != pXInputGetExtended(index, &pressure)))
{
XINPUT_STATE state; XINPUT_STATE state;
if (ERROR_SUCCESS != pXInputGetStateEx(index, &state)) { if (ERROR_SUCCESS != pXInputGetStateEx(index, &state))
{
Deactivate(); Deactivate();
return 0; return 0;
} }
int buttons = state.Gamepad.wButtons; int buttons = state.Gamepad.wButtons;
for (int i = 0; i < 15; i++) { for (int i = 0; i < 15; i++)
{
physicalControlState[i] = ((buttons >> physicalControls[i].id) & 1) << 16; physicalControlState[i] = ((buttons >> physicalControls[i].id) & 1) << 16;
} }
physicalControlState[15] = (int)(state.Gamepad.bLeftTrigger * 257.005); physicalControlState[15] = (int)(state.Gamepad.bLeftTrigger * 257.005);
@ -179,7 +186,9 @@ public:
physicalControlState[18] = ShortToAxis(state.Gamepad.sThumbLY); physicalControlState[18] = ShortToAxis(state.Gamepad.sThumbLY);
physicalControlState[19] = ShortToAxis(state.Gamepad.sThumbRX); physicalControlState[19] = ShortToAxis(state.Gamepad.sThumbRX);
physicalControlState[20] = ShortToAxis(state.Gamepad.sThumbRY); physicalControlState[20] = ShortToAxis(state.Gamepad.sThumbRY);
} else { }
else
{
physicalControlState[0] = (int)(pressure.SCP_UP * FULLY_DOWN); physicalControlState[0] = (int)(pressure.SCP_UP * FULLY_DOWN);
physicalControlState[1] = (int)(pressure.SCP_DOWN * FULLY_DOWN); physicalControlState[1] = (int)(pressure.SCP_DOWN * FULLY_DOWN);
physicalControlState[2] = (int)(pressure.SCP_LEFT * FULLY_DOWN); physicalControlState[2] = (int)(pressure.SCP_LEFT * FULLY_DOWN);
@ -209,10 +218,13 @@ public:
{ {
ps2Vibration[port][slot][motor] = force; ps2Vibration[port][slot][motor] = force;
int newVibration[2] = {0, 0}; int newVibration[2] = {0, 0};
for (int p = 0; p < 2; p++) { for (int p = 0; p < 2; p++)
for (int s = 0; s < 4; s++) { {
for (int s = 0; s < 4; s++)
{
int padtype = config.padConfigs[p][s].type; int padtype = config.padConfigs[p][s].type;
for (int i = 0; i < pads[p][s][padtype].numFFBindings; i++) { 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. // 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]; ForceFeedbackBinding* ffb = &pads[p][s][padtype].ffBindings[i];
newVibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); newVibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
@ -221,16 +233,20 @@ public:
} }
} }
newVibration[0] = abs(newVibration[0]); newVibration[0] = abs(newVibration[0]);
if (newVibration[0] > 65535) { if (newVibration[0] > 65535)
{
newVibration[0] = 65535; newVibration[0] = 65535;
} }
newVibration[1] = abs(newVibration[1]); newVibration[1] = abs(newVibration[1]);
if (newVibration[1] > 65535) { if (newVibration[1] > 65535)
{
newVibration[1] = 65535; newVibration[1] = 65535;
} }
if (newVibration[0] || newVibration[1] || newVibration[0] != xInputVibration.wLeftMotorSpeed || newVibration[1] != xInputVibration.wRightMotorSpeed) { if (newVibration[0] || newVibration[1] || newVibration[0] != xInputVibration.wLeftMotorSpeed || newVibration[1] != xInputVibration.wRightMotorSpeed)
{
XINPUT_VIBRATION newv = {(WORD)newVibration[0], (WORD)newVibration[1]}; XINPUT_VIBRATION newv = {(WORD)newVibration[0], (WORD)newVibration[1]};
if (ERROR_SUCCESS == pXInputSetState(index, &newv)) { if (ERROR_SUCCESS == pXInputSetState(index, &newv))
{
xInputVibration = newv; xInputVibration = newv;
} }
} }
@ -252,8 +268,10 @@ public:
pXInputSetState(index, &xInputVibration); pXInputSetState(index, &xInputVibration);
FreeState(); FreeState();
if (active) { if (active)
if (!--xInputActiveCount) { {
if (!--xInputActiveCount)
{
pXInputEnable(0); pXInputEnable(0);
} }
active = 0; active = 0;
@ -268,7 +286,8 @@ public:
void EnumXInputDevices() void EnumXInputDevices()
{ {
wchar_t temp[30]; wchar_t temp[30];
if (!pXInputSetState) { if (!pXInputSetState)
{
// XInput not installed, so don't repeatedly try to load it. // XInput not installed, so don't repeatedly try to load it.
if (xinputNotInstalled) if (xinputNotInstalled)
return; return;
@ -278,25 +297,30 @@ void EnumXInputDevices()
// Windows 7 systems have issues with it. // Windows 7 systems have issues with it.
// FIXME: Missing FreeLibrary call. // FIXME: Missing FreeLibrary call.
HMODULE hMod = LoadLibrary(L"xinput1_3.dll"); HMODULE hMod = LoadLibrary(L"xinput1_3.dll");
if (hMod == nullptr && IsWindows8OrGreater()) { if (hMod == nullptr && IsWindows8OrGreater())
{
hMod = LoadLibraryEx(L"XInput1_4.dll", nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); hMod = LoadLibraryEx(L"XInput1_4.dll", nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
} }
if (hMod) { if (hMod)
{
if ((pXInputEnable = (_XInputEnable)GetProcAddress(hMod, "XInputEnable")) && if ((pXInputEnable = (_XInputEnable)GetProcAddress(hMod, "XInputEnable")) &&
((pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, (LPCSTR)100)) || // Try Ex version first ((pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, (LPCSTR)100)) || // Try Ex version first
(pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, "XInputGetState")))) { (pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, "XInputGetState"))))
{
pXInputGetExtended = (_XInputGetExtended)GetProcAddress(hMod, "XInputGetExtended"); pXInputGetExtended = (_XInputGetExtended)GetProcAddress(hMod, "XInputGetExtended");
pXInputSetState = (_XInputSetState)GetProcAddress(hMod, "XInputSetState"); pXInputSetState = (_XInputSetState)GetProcAddress(hMod, "XInputSetState");
} }
} }
if (!pXInputSetState) { if (!pXInputSetState)
{
xinputNotInstalled = true; xinputNotInstalled = true;
return; return;
} }
} }
pXInputEnable(1); pXInputEnable(1);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++)
{
wsprintfW(temp, L"XInput Pad %i", i); wsprintfW(temp, L"XInput Pad %i", i);
dm->AddDevice(new XInputDevice(i, temp)); dm->AddDevice(new XInputDevice(i, temp));
} }

View File

@ -950,9 +950,6 @@
<ItemGroup> <ItemGroup>
<Manifest Include="..\PCSX2.manifest" /> <Manifest Include="..\PCSX2.manifest" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Image Include="..\..\PAD\Windows\frog.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" /> <ImportGroup Label="ExtensionTargets" />
</Project> </Project>

View File

@ -2185,9 +2185,4 @@
<Filter>AppHost\Resources</Filter> <Filter>AppHost\Resources</Filter>
</Manifest> </Manifest>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Image Include="..\..\PAD\Windows\frog.ico">
<Filter>System\Ps2\PAD</Filter>
</Image>
</ItemGroup>
</Project> </Project>