reformat lilypad

Note: I'm worried on the EXPORT/CALLBACK behavior on multiple OS
This commit is contained in:
Clang Format 2016-09-04 14:16:34 +02:00 committed by Gregory Hainaut
parent f06f44c30a
commit d6ae5bfafa
35 changed files with 7158 additions and 6772 deletions

File diff suppressed because it is too large Load Diff

View File

@ -30,12 +30,14 @@ enum PadType {
const int numPadTypes = 4; const int numPadTypes = 4;
extern const wchar_t *padTypes[numPadTypes]; extern const wchar_t *padTypes[numPadTypes];
struct PadConfig { struct PadConfig
{
PadType type; PadType type;
u8 autoAnalog; u8 autoAnalog;
}; };
struct GeneralConfig { struct GeneralConfig
{
public: public:
PadConfig padConfigs[2][4]; PadConfig padConfigs[2][4];
@ -47,14 +49,17 @@ public:
// Derived value, calculated by GetInput(). // Derived value, calculated by GetInput().
u8 ignoreKeys; u8 ignoreKeys;
union { union
struct { {
struct
{
u8 forceHide; u8 forceHide;
u8 mouseUnfocus; u8 mouseUnfocus;
u8 background; u8 background;
u8 multipleBinding; u8 multipleBinding;
struct { struct
{
u8 directInput; u8 directInput;
u8 xInput; u8 xInput;
u8 dualShock3; u8 dualShock3;

View File

@ -33,7 +33,8 @@
#include "Linux/JoyEvdev.h" #include "Linux/JoyEvdev.h"
#endif #endif
void EnumDevices(int hideDXXinput) { void EnumDevices(int hideDXXinput)
{
// Needed for enumeration of some device types. // Needed for enumeration of some device types.
dm->ReleaseInput(); dm->ReleaseInput();
InputDeviceManager *oldDm = dm; InputDeviceManager *oldDm = dm;

View File

@ -16,4 +16,3 @@
*/ */
void EnumDevices(int hideDXXinput); void EnumDevices(int hideDXXinput);

View File

@ -25,14 +25,14 @@
Device *dev; Device *dev;
INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam) { INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
{
int i; int i;
HWND hWndList = GetDlgItem(hWnd, IDC_LIST); HWND hWndList = GetDlgItem(hWnd, IDC_LIST);
static int fullRefresh; static int fullRefresh;
if (dev) { if (dev) {
switch (uMsg) { switch (uMsg) {
case WM_INITDIALOG: case WM_INITDIALOG: {
{
fullRefresh = 1; fullRefresh = 1;
SetWindowText(hWnd, dev->displayName); SetWindowText(hWnd, dev->displayName);
LVCOLUMNW c; LVCOLUMNW c;
@ -55,8 +55,7 @@ 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);
@ -72,8 +71,7 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
ListView_SetItem(hWndList, &item); ListView_SetItem(hWndList, &item);
} }
fullRefresh = 1; fullRefresh = 1;
} } else {
else {
for (i = 0; i < dev->numVirtualControls; i++) { for (i = 0; i < dev->numVirtualControls; i++) {
if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i]) { if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i]) {
@ -82,8 +80,7 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
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"-";
@ -106,17 +103,17 @@ 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;
break; case WM_NOTIFY: {
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.
if (n->hdr.idFrom != IDC_LIST || n->hdr.code != LVN_KEYDOWN || n->wVKey != VK_ESCAPE) break; if (n->hdr.idFrom != IDC_LIST || n->hdr.code != LVN_KEYDOWN || n->wVKey != VK_ESCAPE)
break;
} }
case WM_ACTIVATE: case WM_ACTIVATE:
if (uMsg == WM_ACTIVATE && wParam != WA_INACTIVE) break; if (uMsg == WM_ACTIVATE && wParam != WA_INACTIVE)
break;
break; break;
case WM_CLOSE: case WM_CLOSE:
KillTimer(hWnd, 1); KillTimer(hWnd, 1);
@ -132,13 +129,16 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
return 0; return 0;
} }
void Diagnose(int id, HWND hWnd) { 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) dm->DisableDevice(i); if (i != id)
dm->DisableDevice(i);
// Shouldn't be needed. // Shouldn't be needed.
else dm->EnableDevice(i); else
dm->EnableDevice(i);
} }
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIAG), hWnd, DiagDialog); DialogBox(hInst, MAKEINTRESOURCE(IDD_DIAG), hWnd, DiagDialog);
ClearKeyQueue(); ClearKeyQueue();

View File

@ -32,20 +32,29 @@
// media SDK also be installed for a simple macro. This is // media SDK also be installed for a simple macro. This is
// simpler and less silly. // simpler and less silly.
#ifndef SAFE_RELEASE #ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } #define SAFE_RELEASE(p) \
{ \
if (p) { \
(p)->Release(); \
(p) = NULL; \
} \
}
#endif #endif
// Aka htons, without the winsock dependency. // Aka htons, without the winsock dependency.
inline static u16 flipShort(u16 s) { inline static u16 flipShort(u16 s)
{
return (s >> 8) | (s << 8); return (s >> 8) | (s << 8);
} }
// Aka htonl, without the winsock dependency. // Aka htonl, without the winsock dependency.
inline static u32 flipLong(u32 l) { inline static u32 flipLong(u32 l)
{
return (((u32)flipShort((u16)l)) << 16) | flipShort((u16)(l >> 16)); return (((u32)flipShort((u16)l)) << 16) | flipShort((u16)(l >> 16));
} }
static void GUIDtoString(wchar_t *data, const GUID *pg) { static void GUIDtoString(wchar_t *data, const GUID *pg)
{
wsprintfW(data, L"%08X-%04X-%04X-%04X-%04X%08X", wsprintfW(data, L"%08X-%04X-%04X-%04X-%04X%08X",
pg->Data1, (u32)pg->Data2, (u32)pg->Data3, pg->Data1, (u32)pg->Data2, (u32)pg->Data3,
flipShort(((u16 *)pg->Data4)[0]), flipShort(((u16 *)pg->Data4)[0]),
@ -53,7 +62,8 @@ static void GUIDtoString(wchar_t *data, const GUID *pg) {
flipLong(((u32 *)pg->Data4)[1])); flipLong(((u32 *)pg->Data4)[1]));
} }
struct DirectInput8Data { struct DirectInput8Data
{
IDirectInput8 *lpDI8; IDirectInput8 *lpDI8;
int refCount; int refCount;
int deviceCount; int deviceCount;
@ -61,14 +71,17 @@ struct DirectInput8Data {
DirectInput8Data di8d = {0, 0, 0}; 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))) return 0; if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void **)&di8d.lpDI8, 0)))
return 0;
} }
di8d.refCount++; di8d.refCount++;
return di8d.lpDI8; return di8d.lpDI8;
} }
void ReleaseDirectInput() { void ReleaseDirectInput()
{
if (di8d.refCount) { if (di8d.refCount) {
di8d.refCount--; di8d.refCount--;
if (!di8d.refCount) { if (!di8d.refCount) {
@ -78,9 +91,11 @@ void ReleaseDirectInput() {
} }
} }
static int StringToGUID(GUID *pg, wchar_t *dataw) { static int StringToGUID(GUID *pg, wchar_t *dataw)
{
char data[100]; char data[100];
if (wcslen(dataw) > 50) return 0; if (wcslen(dataw) > 50)
return 0;
int w = 0; int w = 0;
while (dataw[w]) { while (dataw[w]) {
data[w] = (char)dataw[w]; data[w] = (char)dataw[w];
@ -100,20 +115,24 @@ static int StringToGUID(GUID *pg, wchar_t *dataw) {
} }
struct DI8Effect { struct DI8Effect
{
IDirectInputEffect *die; IDirectInputEffect *die;
int scale; int scale;
}; };
BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef); BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef);
class DirectInputDevice : public Device { class DirectInputDevice : public Device
{
public: public:
DI8Effect *diEffects; DI8Effect *diEffects;
IDirectInputDevice8 *did; IDirectInputDevice8 *did;
GUID guidInstance; GUID guidInstance;
DirectInputDevice(DeviceType type, IDirectInputDevice8* did, wchar_t *displayName, wchar_t *instanceID, wchar_t *productID, GUID guid) : Device(DI, type, displayName, instanceID, productID) { DirectInputDevice(DeviceType type, IDirectInputDevice8 *did, wchar_t *displayName, wchar_t *instanceID, wchar_t *productID, GUID guid)
: Device(DI, type, displayName, instanceID, productID)
{
diEffects = 0; diEffects = 0;
guidInstance = guid; guidInstance = guid;
this->did = 0; this->did = 0;
@ -122,7 +141,8 @@ public:
did->Release(); did->Release();
} }
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;
@ -142,7 +162,8 @@ public:
if (die) { if (die) {
DIEFFECT dieffect; DIEFFECT dieffect;
memset(&dieffect, 0, sizeof(dieffect)); memset(&dieffect, 0, sizeof(dieffect));
union { union
{
DIPERIODIC periodic; DIPERIODIC periodic;
DIRAMPFORCE ramp; DIRAMPFORCE ramp;
DICONSTANTFORCE constant; DICONSTANTFORCE constant;
@ -151,20 +172,19 @@ public:
dieffect.dwSize = sizeof(dieffect); dieffect.dwSize = sizeof(dieffect);
dieffect.lpvTypeSpecificParams = &periodic; dieffect.lpvTypeSpecificParams = &periodic;
int magnitude = abs((int)((force * 10000 * (__int64)diEffects[index].scale) / BASE_SENSITIVITY / 255)); int magnitude = abs((int)((force * 10000 * (__int64)diEffects[index].scale) / BASE_SENSITIVITY / 255));
if (magnitude > 10000) magnitude = 10000; if (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;
} }
@ -174,11 +194,13 @@ public:
} }
} }
int Activate(InitInfo *initInfo) { int Activate(InitInfo *initInfo)
{
int i; int i;
IDirectInput8 *di8 = GetDirectInput(); IDirectInput8 *di8 = GetDirectInput();
Deactivate(); Deactivate();
if (!di8) return 0; if (!di8)
return 0;
if (DI_OK != di8->CreateDevice(guidInstance, &did, 0)) { if (DI_OK != di8->CreateDevice(guidInstance, &did, 0)) {
ReleaseDirectInput(); ReleaseDirectInput();
did = 0; did = 0;
@ -230,11 +252,9 @@ public:
// 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) {
@ -255,7 +275,8 @@ public:
b = &pads[port][slot].ffBindings[i - subIndex]; b = &pads[port][slot].ffBindings[i - subIndex];
ForceFeedbackEffectType *eff = ffEffectTypes + b->effectIndex; ForceFeedbackEffectType *eff = ffEffectTypes + b->effectIndex;
GUID guid; GUID guid;
if (!StringToGUID(&guid, eff->effectID)) continue; if (!StringToGUID(&guid, eff->effectID))
continue;
DIEFFECT dieffect; DIEFFECT dieffect;
memset(&dieffect, 0, sizeof(dieffect)); memset(&dieffect, 0, sizeof(dieffect));
@ -264,7 +285,8 @@ public:
dieffect.dwDuration = 1000000; dieffect.dwDuration = 1000000;
dieffect.dwGain = 10000; dieffect.dwGain = 10000;
dieffect.dwTriggerButton = DIEB_NOTRIGGER; dieffect.dwTriggerButton = DIEB_NOTRIGGER;
union { union
{
DIPERIODIC pediodic; DIPERIODIC pediodic;
DIRAMPFORCE ramp; DIRAMPFORCE ramp;
DICONSTANTFORCE constant; DICONSTANTFORCE constant;
@ -272,11 +294,9 @@ public:
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;
@ -321,8 +341,10 @@ public:
return 1; return 1;
} }
int Update() { int Update()
if (!active) return 0; {
if (!active)
return 0;
if (numPhysicalControls) { if (numPhysicalControls) {
HRESULT res = did->Poll(); HRESULT res = did->Poll();
// ?? // ??
@ -334,8 +356,7 @@ public:
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;
} }
} }
@ -343,7 +364,8 @@ public:
return 1; return 1;
} }
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++) {
@ -353,7 +375,8 @@ public:
return count; return count;
} }
void Deactivate() { void Deactivate()
{
FreeState(); FreeState();
if (diEffects) { if (diEffects) {
int count = GetFFBindingCount(); int count = GetFFBindingCount();
@ -375,24 +398,23 @@ public:
} }
} }
~DirectInputDevice() { ~DirectInputDevice()
{
} }
}; };
BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef) { 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];
@ -402,7 +424,8 @@ BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef) {
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
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);
@ -426,7 +449,8 @@ BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOI
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]) break; if (!lpddoi->tszName[0])
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) {
@ -434,9 +458,11 @@ BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOI
s2++; s2++;
} }
// If perfect match with one of last 4 names, break. // If perfect match with one of last 4 names, break.
if (!*s1 && !*s2) break; if (!*s1 && !*s2)
break;
while (s1 != lpddoi->tszName && (s1[-1] >= '0' && s1[-1] <= '9')) s1--; while (s1 != lpddoi->tszName && (s1[-1] >= '0' && s1[-1] <= '9'))
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';
@ -447,7 +473,8 @@ BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOI
} }
// If perfect match other than final number > 30, then break. // If perfect match other than final number > 30, then break.
// takes care of "button xx" case without causing issues with F keys. // takes care of "button xx" case without causing issues with F keys.
if (!*s1 && !*s2 && check > 30) break; if (!*s1 && !*s2 && check > 30)
break;
} }
if (i != did->numPhysicalControls - 4) { if (i != did->numPhysicalControls - 4) {
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
@ -498,9 +525,15 @@ BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput )
if (FAILED(hr) || pIWbemLocator == NULL) if (FAILED(hr) || pIWbemLocator == NULL)
goto LCleanup; goto LCleanup;
bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup; bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2");
bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup; if (bstrNamespace == NULL)
bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; goto LCleanup;
bstrClassName = SysAllocString(L"Win32_PNPEntity");
if (bstrClassName == NULL)
goto LCleanup;
bstrDeviceID = SysAllocString(L"DeviceID");
if (bstrDeviceID == NULL)
goto LCleanup;
// Connect to WMI // Connect to WMI
hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L, hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L,
@ -517,8 +550,7 @@ 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))
@ -526,16 +558,13 @@ 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_");
@ -549,8 +578,7 @@ BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput )
// 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;
} }
@ -580,23 +608,23 @@ LCleanup:
} }
struct DeviceEnumInfo { struct DeviceEnumInfo
{
IDirectInput8 *di8; IDirectInput8 *di8;
int ignoreXInput; int ignoreXInput;
}; };
BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
IDirectInput8 *di8 = ((DeviceEnumInfo *)pvRef)->di8; IDirectInput8 *di8 = ((DeviceEnumInfo *)pvRef)->di8;
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;
} }
@ -610,8 +638,7 @@ BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
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;
@ -619,8 +646,7 @@ BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
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;
} }
} }
@ -628,13 +654,14 @@ BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
void EnumDirectInputDevices(int ignoreXInput) { void EnumDirectInputDevices(int ignoreXInput)
{
DeviceEnumInfo enumInfo; DeviceEnumInfo enumInfo;
enumInfo.di8 = GetDirectInput(); enumInfo.di8 = GetDirectInput();
if (!enumInfo.di8) return; if (!enumInfo.di8)
return;
enumInfo.ignoreXInput = ignoreXInput; enumInfo.ignoreXInput = ignoreXInput;
di8d.deviceCount = 0; di8d.deviceCount = 0;
enumInfo.di8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, &enumInfo, DIEDFL_ATTACHEDONLY); enumInfo.di8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, &enumInfo, DIEDFL_ATTACHEDONLY);
ReleaseDirectInput(); ReleaseDirectInput();
} }

View File

@ -62,14 +62,16 @@ _usb_control_msg pusb_control_msg;
HMODULE hModLibusb = 0; HMODULE hModLibusb = 0;
void UninitLibUsb() { void UninitLibUsb()
{
if (hModLibusb) { if (hModLibusb) {
FreeLibrary(hModLibusb); FreeLibrary(hModLibusb);
hModLibusb = 0; hModLibusb = 0;
} }
} }
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);
@ -90,7 +92,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;
} }
@ -99,7 +102,8 @@ void DS3Enum(unsigned int time) {
pusb_find_devices(); pusb_find_devices();
} }
void DS3Check(unsigned int time) { void DS3Check(unsigned int time)
{
if (time - lastDS3Check < DOUBLE_CHECK_DELAY) { if (time - lastDS3Check < DOUBLE_CHECK_DELAY) {
return; return;
} }
@ -115,7 +119,8 @@ void DS3Check(unsigned int time) {
} }
} }
int InitLibUsb() { int InitLibUsb()
{
if (hModLibusb) { if (hModLibusb) {
return 1; return 1;
} }
@ -137,18 +142,21 @@ int InitLibUsb() {
return 0; return 0;
} }
int DualShock3Possible() { int DualShock3Possible()
{
return InitLibUsb(); return InitLibUsb();
} }
#include <pshpack1.h> #include <pshpack1.h>
struct MotorState { struct MotorState
{
unsigned char duration; unsigned char duration;
unsigned char force; unsigned char force;
}; };
struct LightState { struct LightState
{
// 0xFF makes it stay on. // 0xFF makes it stay on.
unsigned char duration; unsigned char duration;
// Have to make one or the other non-zero to turn on light. // Have to make one or the other non-zero to turn on light.
@ -160,7 +168,8 @@ struct LightState {
}; };
// Data sent to DS3 to set state. // Data sent to DS3 to set state.
struct DS3Command { struct DS3Command
{
unsigned char id; unsigned char id;
unsigned char unsure; unsigned char unsure;
// Small is first, then big. // Small is first, then big.
@ -175,21 +184,25 @@ struct DS3Command {
#include <poppack.h> #include <poppack.h>
int CharToAxis(unsigned char c) { int CharToAxis(unsigned char c)
{
int v = (int)c + ((unsigned int)c >> 7); int v = (int)c + ((unsigned int)c >> 7);
return ((c - 128) * FULLY_DOWN) >> 7; return ((c - 128) * FULLY_DOWN) >> 7;
} }
int CharToButton(unsigned char c) { int CharToButton(unsigned char c)
{
int v = (int)c + ((unsigned int)c >> 7); int v = (int)c + ((unsigned int)c >> 7);
return (v * FULLY_DOWN) >> 8; return (v * FULLY_DOWN) >> 8;
} }
class DualShock3Device : public Device { class DualShock3Device : public Device
{
// Cached last vibration values by pad and motor. // Cached last vibration values by pad and motor.
// Need this, as only one value is changed at a time. // Need this, as only one value is changed at a time.
int ps2Vibration[2][4][2]; int ps2Vibration[2][4][2];
int vibration[2]; int vibration[2];
public: public:
int index; int index;
HANDLE hFile; HANDLE hFile;
@ -205,12 +218,14 @@ public:
int writeQueued; int writeQueued;
int writing; int writing;
int StartRead() { int StartRead()
{
int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop); int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop);
return (res || GetLastError() == ERROR_IO_PENDING); return (res || GetLastError() == ERROR_IO_PENDING);
} }
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++;
@ -218,7 +233,8 @@ public:
} }
} }
int StartWrite() { int StartWrite()
{
if (!writing && writeQueued) { if (!writing && writeQueued) {
lastWrite = GetTickCount(); lastWrite = GetTickCount();
writing++; writing++;
@ -227,7 +243,8 @@ public:
sendState.motors[1].duration = 0x50; sendState.motors[1].duration = 0x50;
int bigForce = vibration[0] * 256 / FULLY_DOWN; int bigForce = vibration[0] * 256 / FULLY_DOWN;
if (bigForce > 255) bigForce = 255; if (bigForce > 255)
bigForce = 255;
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.
@ -243,7 +260,9 @@ public:
return 1; return 1;
} }
DualShock3Device(int index, wchar_t *name, wchar_t *path) : Device(DS3, OTHER, name, path, L"DualShock 3") { DualShock3Device(int index, wchar_t *name, wchar_t *path)
: Device(DS3, OTHER, name, path, L"DualShock 3")
{
writeCount = 0; writeCount = 0;
writing = 0; writing = 0;
writeQueued = 0; writeQueued = 0;
@ -263,8 +282,7 @@ public:
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);
} }
} }
@ -277,7 +295,8 @@ public:
hFile = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE;
} }
wchar_t *GetPhysicalControlName(PhysicalControl *c) { wchar_t *GetPhysicalControlName(PhysicalControl *c)
{
const static wchar_t *names[] = { const static wchar_t *names[] = {
L"Square", L"Square",
L"Cross", L"Cross",
@ -310,8 +329,10 @@ public:
return Device::GetPhysicalControlName(c); return Device::GetPhysicalControlName(c);
} }
int Activate(InitInfo *initInfo) { int Activate(InitInfo *initInfo)
if (active) Deactivate(); {
if (active)
Deactivate();
// Give grace period before get mad. // Give grace period before get mad.
lastWrite = dataLastReceived = GetTickCount(); lastWrite = dataLastReceived = GetTickCount();
readop.hEvent = CreateEvent(0, 0, 0, 0); readop.hEvent = CreateEvent(0, 0, 0, 0);
@ -327,12 +348,13 @@ public:
return 1; return 1;
} }
int Update() { int Update()
if (!active) return 0; {
if (!active)
return 0;
HANDLE h[2] = { HANDLE h[2] = {
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();
@ -370,8 +392,7 @@ 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();
@ -380,8 +401,7 @@ public:
Deactivate(); Deactivate();
return 0; return 0;
} }
} } else {
else {
if (time - dataLastReceived >= DEVICE_CHECK_DELAY) { if (time - dataLastReceived >= DEVICE_CHECK_DELAY) {
if (time - dataLastReceived >= DEVICE_ENUM_DELAY) { if (time - dataLastReceived >= DEVICE_ENUM_DELAY) {
DS3Enum(time); DS3Enum(time);
@ -395,7 +415,8 @@ public:
return 1; return 1;
} }
void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) { void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force)
{
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++) {
@ -413,7 +434,8 @@ public:
QueueWrite(); QueueWrite();
} }
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) { void SetEffect(ForceFeedbackBinding *binding, unsigned char force)
{
PadBindings pBackup = pads[0][0]; PadBindings pBackup = pads[0][0];
pads[0][0].ffBindings = binding; pads[0][0].ffBindings = binding;
pads[0][0].numFFBindings = 1; pads[0][0].numFFBindings = 1;
@ -421,7 +443,8 @@ public:
pads[0][0] = pBackup; pads[0][0] = pBackup;
} }
void Deactivate() { void Deactivate()
{
if (hFile != INVALID_HANDLE_VALUE) { if (hFile != INVALID_HANDLE_VALUE) {
CancelIo(hFile); CancelIo(hFile);
CloseHandle(hFile); CloseHandle(hFile);
@ -442,17 +465,21 @@ public:
active = 0; active = 0;
} }
~DualShock3Device() { ~DualShock3Device()
{
} }
}; };
void EnumDualShock3s() { void EnumDualShock3s()
if (!InitLibUsb()) return; {
if (!InitLibUsb())
return;
HidDeviceInfo *foundDevs = 0; HidDeviceInfo *foundDevs = 0;
int numDevs = FindHids(&foundDevs, VID, PID); int numDevs = FindHids(&foundDevs, VID, PID);
if (!numDevs) return; if (!numDevs)
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 &&

View File

@ -45,7 +45,8 @@ typedef int64_t __int64;
#include <cstdarg> #include <cstdarg>
template <typename Array> template <typename Array>
void wsprintfW(Array& buf, const wchar_t *format, ...) { void wsprintfW(Array &buf, const wchar_t *format, ...)
{
va_list a; va_list a;
va_start(a, format); va_start(a, format);
@ -55,7 +56,8 @@ void wsprintfW(Array& buf, const wchar_t *format, ...) {
} }
template <typename Array> template <typename Array>
void wsprintf(Array& buf, const wchar_t *format, ...) { void wsprintf(Array &buf, const wchar_t *format, ...)
{
va_list a; va_list a;
va_start(a, format); va_start(a, format);
@ -64,13 +66,15 @@ void wsprintf(Array& buf, const wchar_t *format, ...) {
va_end(a); va_end(a);
} }
static inline int wcsicmp(const wchar_t* w1, const wchar_t* w2) { static inline int wcsicmp(const wchar_t *w1, const wchar_t *w2)
{
// I didn't find a way to put ignore case ... // I didn't find a way to put ignore case ...
return wcscmp(w1, w2); return wcscmp(w1, w2);
} }
#include <sys/time.h> #include <sys/time.h>
static inline unsigned int timeGetTime() { static inline unsigned int timeGetTime()
{
struct timeval now; struct timeval now;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
uint64_t ms = (now.tv_usec / 1000) + ((uint64_t)now.tv_sec * 1000); uint64_t ms = (now.tv_usec / 1000) + ((uint64_t)now.tv_sec * 1000);
@ -136,7 +140,8 @@ extern HINSTANCE hInst;
// Needed for config screen // Needed for config screen
void GetNameAndVersionString(wchar_t *out); void GetNameAndVersionString(wchar_t *out);
typedef struct { typedef struct
{
unsigned char controllerType; unsigned char controllerType;
unsigned short buttonStatus; unsigned short buttonStatus;
unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY; unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY;
@ -144,27 +149,51 @@ typedef struct {
unsigned char reserved[91]; unsigned char reserved[91];
} PadDataS; } PadDataS;
EXPORT_C_(void) PADupdate(int pad); EXPORT_C_(void)
EXPORT_C_(u32) PS2EgetLibType(void); PADupdate(int pad);
EXPORT_C_(u32) PS2EgetLibVersion2(u32 type); EXPORT_C_(u32)
EXPORT_C_(char*) PSEgetLibName(); PS2EgetLibType(void);
EXPORT_C_(char*) PS2EgetLibName(void); EXPORT_C_(u32)
EXPORT_C_(void) PADshutdown(); PS2EgetLibVersion2(u32 type);
EXPORT_C_(s32) PADinit(u32 flags); EXPORT_C_(char *)
EXPORT_C_(s32) PADopen(void *pDsp); PSEgetLibName();
EXPORT_C_(void) PADclose(); EXPORT_C_(char *)
EXPORT_C_(u8) PADstartPoll(int pad); PS2EgetLibName(void);
EXPORT_C_(u8) PADpoll(u8 value); EXPORT_C_(void)
EXPORT_C_(u32) PADquery(); PADshutdown();
EXPORT_C_(void) PADabout(); EXPORT_C_(s32)
EXPORT_C_(s32) PADtest(); PADinit(u32 flags);
EXPORT_C_(keyEvent*) PADkeyEvent(); EXPORT_C_(s32)
EXPORT_C_(u32) PADreadPort1 (PadDataS* pads); PADopen(void *pDsp);
EXPORT_C_(u32) PADreadPort2 (PadDataS* pads); EXPORT_C_(void)
EXPORT_C_(u32) PSEgetLibType(); PADclose();
EXPORT_C_(u32) PSEgetLibVersion(); EXPORT_C_(u8)
EXPORT_C_(void) PADconfigure(); PADstartPoll(int pad);
EXPORT_C_(s32) PADfreeze(int mode, freezeData *data); EXPORT_C_(u8)
EXPORT_C_(s32) PADsetSlot(u8 port, u8 slot); PADpoll(u8 value);
EXPORT_C_(s32) PADqueryMtap(u8 port); EXPORT_C_(u32)
EXPORT_C_(void) PADsetSettingsDir(const char *dir); PADquery();
EXPORT_C_(void)
PADabout();
EXPORT_C_(s32)
PADtest();
EXPORT_C_(keyEvent *)
PADkeyEvent();
EXPORT_C_(u32)
PADreadPort1(PadDataS *pads);
EXPORT_C_(u32)
PADreadPort2(PadDataS *pads);
EXPORT_C_(u32)
PSEgetLibType();
EXPORT_C_(u32)
PSEgetLibVersion();
EXPORT_C_(void)
PADconfigure();
EXPORT_C_(s32)
PADfreeze(int mode, freezeData *data);
EXPORT_C_(s32)
PADsetSlot(u8 port, u8 slot);
EXPORT_C_(s32)
PADqueryMtap(u8 port);
EXPORT_C_(void)
PADsetSettingsDir(const char *dir);

View File

@ -20,7 +20,8 @@
#include <setupapi.h> #include <setupapi.h>
#include <hidsdi.h> #include <hidsdi.h>
int FindHids(HidDeviceInfo **foundDevs, int vid, int pid) { int FindHids(HidDeviceInfo **foundDevs, int vid, int pid)
{
GUID GUID_DEVINTERFACE_HID; GUID GUID_DEVINTERFACE_HID;
int numFoundDevs = 0; int numFoundDevs = 0;
*foundDevs = 0; *foundDevs = 0;
@ -33,15 +34,18 @@ int FindHids(HidDeviceInfo **foundDevs, int vid, int pid) {
DWORD size = 0; DWORD size = 0;
SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0); SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !size) continue; if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !size)
continue;
SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(size); SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(size);
if (!devInterfaceDetails) continue; if (!devInterfaceDetails)
continue;
devInterfaceDetails->cbSize = sizeof(*devInterfaceDetails); devInterfaceDetails->cbSize = sizeof(*devInterfaceDetails);
SP_DEVINFO_DATA devInfoData; SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, devInterfaceDetails, size, &size, &devInfoData)) continue; if (!SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, devInterfaceDetails, size, &size, &devInfoData))
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) {

View File

@ -20,7 +20,8 @@
#include <hidsdi.h> #include <hidsdi.h>
struct HidDeviceInfo { struct HidDeviceInfo
{
HIDP_CAPS caps; HIDP_CAPS caps;
wchar_t *path; wchar_t *path;
unsigned short vid; unsigned short vid;

View File

@ -21,11 +21,13 @@
InputDeviceManager *dm = 0; InputDeviceManager *dm = 0;
InputDeviceManager::InputDeviceManager() { InputDeviceManager::InputDeviceManager()
{
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
} }
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];
} }
@ -34,11 +36,13 @@ void InputDeviceManager::ClearDevices() {
numDevices = 0; numDevices = 0;
} }
InputDeviceManager::~InputDeviceManager() { InputDeviceManager::~InputDeviceManager()
{
ClearDevices(); ClearDevices();
} }
Device::Device(DeviceAPI api, DeviceType d, const wchar_t *displayName, const wchar_t *instanceID, const wchar_t *productID) { Device::Device(DeviceAPI api, DeviceType d, const wchar_t *displayName, const wchar_t *instanceID, const wchar_t *productID)
{
memset(pads, 0, sizeof(pads)); memset(pads, 0, sizeof(pads));
this->api = api; this->api = api;
type = d; type = d;
@ -73,14 +77,17 @@ Device::Device(DeviceAPI api, DeviceType d, const wchar_t *displayName, const wc
numFFAxes = 0; numFFAxes = 0;
} }
void Device::FreeState() { void Device::FreeState()
if (virtualControlState) free(virtualControlState); {
if (virtualControlState)
free(virtualControlState);
virtualControlState = 0; virtualControlState = 0;
oldVirtualControlState = 0; oldVirtualControlState = 0;
physicalControlState = 0; physicalControlState = 0;
} }
Device::~Device() { Device::~Device()
{
Deactivate(); Deactivate();
// Generally called by deactivate, but just in case... // Generally called by deactivate, but just in case...
FreeState(); FreeState();
@ -97,7 +104,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) free(physicalControls[i].name); if (physicalControls[i].name)
free(physicalControls[i].name);
} }
free(physicalControls); free(physicalControls);
@ -119,7 +127,8 @@ Device::~Device() {
} }
} }
void Device::AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID, EffectType type) { void Device::AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID, EffectType type)
{
ffEffectTypes = (ForceFeedbackEffectType *)realloc(ffEffectTypes, sizeof(ForceFeedbackEffectType) * (numFFEffectTypes + 1)); ffEffectTypes = (ForceFeedbackEffectType *)realloc(ffEffectTypes, sizeof(ForceFeedbackEffectType) * (numFFEffectTypes + 1));
ffEffectTypes[numFFEffectTypes].displayName = wcsdup(displayName); ffEffectTypes[numFFEffectTypes].displayName = wcsdup(displayName);
ffEffectTypes[numFFEffectTypes].effectID = wcsdup(effectID); ffEffectTypes[numFFEffectTypes].effectID = wcsdup(effectID);
@ -127,7 +136,8 @@ void Device::AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID
numFFEffectTypes++; numFFEffectTypes++;
} }
void Device::AddFFAxis(const wchar_t *displayName, int id) { void Device::AddFFAxis(const wchar_t *displayName, int id)
{
ffAxes = (ForceFeedbackAxis *)realloc(ffAxes, sizeof(ForceFeedbackAxis) * (numFFAxes + 1)); ffAxes = (ForceFeedbackAxis *)realloc(ffAxes, sizeof(ForceFeedbackAxis) * (numFFAxes + 1));
ffAxes[numFFAxes].id = id; ffAxes[numFFAxes].id = id;
ffAxes[numFFAxes].displayName = wcsdup(displayName); ffAxes[numFFAxes].displayName = wcsdup(displayName);
@ -155,22 +165,26 @@ void Device::AddFFAxis(const wchar_t *displayName, int id) {
} }
} }
void Device::AllocState() { void Device::AllocState()
{
FreeState(); FreeState();
virtualControlState = (int *)calloc(numVirtualControls + numVirtualControls + numPhysicalControls, sizeof(int)); virtualControlState = (int *)calloc(numVirtualControls + numVirtualControls + numPhysicalControls, sizeof(int));
oldVirtualControlState = virtualControlState + numVirtualControls; oldVirtualControlState = virtualControlState + numVirtualControls;
physicalControlState = oldVirtualControlState + numVirtualControls; physicalControlState = oldVirtualControlState + numVirtualControls;
} }
void Device::FlipState() { void Device::FlipState()
{
memcpy(oldVirtualControlState, virtualControlState, sizeof(int) * numVirtualControls); memcpy(oldVirtualControlState, virtualControlState, sizeof(int) * numVirtualControls);
} }
void Device::PostRead() { void Device::PostRead()
{
FlipState(); FlipState();
} }
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;
@ -191,30 +205,29 @@ void Device::CalcVirtualState() {
break; break;
} }
} }
if (i<numPhysicalControls) continue; if (i < numPhysicalControls)
continue;
} }
int event = KEYPRESS; int event = KEYPRESS;
if (!(virtualControlState[index]>>15)) event = KEYRELEASE; if (!(virtualControlState[index] >> 15))
event = KEYRELEASE;
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;
@ -243,7 +256,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;
@ -251,7 +265,8 @@ VirtualControl *Device::GetVirtualControl(unsigned int uid) {
return 0; return 0;
} }
VirtualControl *Device::AddVirtualControl(unsigned int uid, int physicalControlIndex) { VirtualControl *Device::AddVirtualControl(unsigned int uid, int physicalControlIndex)
{
// 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();
@ -267,7 +282,8 @@ VirtualControl *Device::AddVirtualControl(unsigned int uid, int physicalControlI
return c; return c;
} }
PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name) { PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name)
{
// 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();
@ -279,19 +295,18 @@ PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id,
memset(control, 0, sizeof(PhysicalControl)); memset(control, 0, sizeof(PhysicalControl));
control->type = type; control->type = type;
control->id = id; control->id = id;
if (name) control->name = wcsdup(name); if (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);
@ -302,7 +317,8 @@ PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id,
return control; return control;
} }
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)
{
for (int i = 0; i < pads[port][slot].numFFBindings; i++) { for (int i = 0; i < pads[port][slot].numFFBindings; i++) {
ForceFeedbackBinding *binding = pads[port][slot].ffBindings + i; ForceFeedbackBinding *binding = pads[port][slot].ffBindings + i;
if (binding->motor == motor) { if (binding->motor == motor) {
@ -311,29 +327,29 @@ 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;
} }
wchar_t *Device::GetVirtualControlName(VirtualControl *control) { 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) baseName = GetPhysicalControlName(&physicalControls[control->physicalControlIndex]); if (!baseName)
baseName = GetPhysicalControlName(&physicalControls[control->physicalControlIndex]);
} }
unsigned int uid = control->uid; unsigned int uid = control->uid;
if (!baseName) { if (!baseName) {
@ -341,49 +357,51 @@ wchar_t *Device::GetVirtualControlName(VirtualControl *control) {
} }
uid &= 0xFF000000; uid &= 0xFF000000;
int len = (int)wcslen(baseName); int len = (int)wcslen(baseName);
if (len > 99) len = 99; if (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) len = 95; if (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");
} }
} }
return temp; return temp;
} }
wchar_t *Device::GetPhysicalControlName(PhysicalControl *control) { wchar_t *Device::GetPhysicalControlName(PhysicalControl *control)
if (control->name) return control->name; {
if (control->name)
return control->name;
return GetDefaultControlName(control->id, control->type); return GetDefaultControlName(control->id, control->type);
} }
void InputDeviceManager::AddDevice(Device *d) { void InputDeviceManager::AddDevice(Device *d)
{
devices = (Device **)realloc(devices, sizeof(Device *) * (numDevices + 1)); devices = (Device **)realloc(devices, sizeof(Device *) * (numDevices + 1));
devices[numDevices++] = d; devices[numDevices++] = 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]->enabled) {
if (!devices[i]->active) { if (!devices[i]->active) {
if (!devices[i]->Activate(info) || !devices[i]->Update()) continue; if (!devices[i]->Activate(info) || !devices[i]->Update())
continue;
devices[i]->CalcVirtualState(); devices[i]->CalcVirtualState();
devices[i]->PostRead(); devices[i]->PostRead();
} }
@ -393,14 +411,16 @@ 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();
} }
} }
Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value) { Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value)
{
int i, j; int i, j;
Update(info); Update(info);
int bestDiff = FULLY_DOWN / 2; int bestDiff = FULLY_DOWN / 2;
@ -408,8 +428,10 @@ Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, i
for (i = 0; i < numDevices; i++) { for (i = 0; i < numDevices; i++) {
if (devices[i]->active) { if (devices[i]->active) {
for (j = 0; j < devices[i]->numVirtualControls; j++) { for (j = 0; j < devices[i]->numVirtualControls; j++) {
if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j]) continue; if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j])
if (devices[i]->virtualControls[j].uid & UID_POV) continue; continue;
if (devices[i]->virtualControls[j].uid & UID_POV)
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])) {
@ -427,14 +449,14 @@ Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, i
} }
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)) continue; if ((((devices[i]->virtualControls[j].uid >> 16) & 0xFF) != ABSAXIS))
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;
} }
@ -445,8 +467,7 @@ Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, 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];
} }
} }
@ -459,13 +480,16 @@ Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, i
return bestDevice; return bestDevice;
} }
void InputDeviceManager::ReleaseInput() { void InputDeviceManager::ReleaseInput()
{
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++) {
if (devices[i]->active) devices[i]->Deactivate(); if (devices[i]->active)
devices[i]->Deactivate();
} }
} }
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);
@ -473,20 +497,23 @@ 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);
} }
} }
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];
@ -495,14 +522,17 @@ ForceFeedbackEffectType *Device::GetForcefeedbackEffect(wchar_t *id) {
return 0; return 0;
} }
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) return &ffAxes[i]; if (ffAxes[i].id == id)
return &ffAxes[i];
} }
return 0; return 0;
} }
void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices) { void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices)
{
int *oldMatches = (int *)malloc(sizeof(int) * numOldDevices); int *oldMatches = (int *)malloc(sizeof(int) * numOldDevices);
int *matches = (int *)malloc(sizeof(int) * numDevices); int *matches = (int *)malloc(sizeof(int) * numDevices);
int i, j, port, slot; int i, j, port, slot;
@ -525,7 +555,8 @@ 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) continue; if (oldMatches[i] >= 0)
continue;
for (j = 0; j < numDevices; j++) { for (j = 0; j < numDevices; j++) {
if (matches[j] >= 0) { if (matches[j] >= 0) {
continue; continue;
@ -545,7 +576,8 @@ void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices) {
} }
for (i = 0; i < numOldDevices; i++) { for (i = 0; i < numOldDevices; i++) {
if (oldMatches[i] == -2) continue; if (oldMatches[i] == -2)
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);
@ -567,8 +599,7 @@ 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 (slot = 0; slot < 4; slot++) {
@ -613,7 +644,8 @@ void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices) {
free(matches); free(matches);
} }
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) {
@ -621,4 +653,3 @@ void InputDeviceManager::SetEffect(unsigned char port, unsigned int slot, unsign
} }
} }
} }

View File

@ -65,7 +65,8 @@ enum ControlType {
#define BINARY_BUTTON (PSHBTN | TGLBTN) #define BINARY_BUTTON (PSHBTN | TGLBTN)
#define AXIS 3 #define AXIS 3
struct Binding { struct Binding
{
int controlIndex; int controlIndex;
int command; int command;
int sensitivity; int sensitivity;
@ -88,7 +89,8 @@ struct Binding {
// and individual axis/pov directions. Not that pov controls // and individual axis/pov directions. Not that pov controls
// cannot actually be bound, but when trying to bind as an axis, // cannot actually be bound, but when trying to bind as an axis,
// all directions are assigned individually. // all directions are assigned individually.
struct VirtualControl { struct VirtualControl
{
// Unique id for control, given device. Based on source control's id, // Unique id for control, given device. Based on source control's id,
// source control type, axis/pov flags if it's a pov/axis (Rather than // source control type, axis/pov flags if it's a pov/axis (Rather than
// a button or a pov/axis control's individual button), and an index, // a button or a pov/axis control's individual button), and an index,
@ -103,7 +105,8 @@ struct VirtualControl {
// updates their state, standard function then populates // updates their state, standard function then populates
// the VirtualControls and queues the keyboard messages, if // the VirtualControls and queues the keyboard messages, if
// needed. // needed.
struct PhysicalControl { struct PhysicalControl
{
// index of the first virtual control corresponding to this. // index of the first virtual control corresponding to this.
// Buttons have 1 virtual control, axes 3, and povs 5, all // Buttons have 1 virtual control, axes 3, and povs 5, all
// in a row. // in a row.
@ -152,11 +155,13 @@ enum EffectType {
// Order matches ForceFeedbackAxis order. force of 0 means to // Order matches ForceFeedbackAxis order. force of 0 means to
// ignore that axis completely. Force of 1 or -1 means to initialize // ignore that axis completely. Force of 1 or -1 means to initialize
// the axis with minimum force (Possibly 0 force), if applicable. // the axis with minimum force (Possibly 0 force), if applicable.
struct AxisEffectInfo { struct AxisEffectInfo
{
int force; int force;
}; };
struct ForceFeedbackBinding { struct ForceFeedbackBinding
{
AxisEffectInfo *axes; AxisEffectInfo *axes;
int effectIndex; int effectIndex;
unsigned char motor; unsigned char motor;
@ -164,7 +169,8 @@ struct ForceFeedbackBinding {
// Bindings listed by effect, so I don't have to bother with // Bindings listed by effect, so I don't have to bother with
// indexing effects. // indexing effects.
struct ForceFeedbackEffectType { struct ForceFeedbackEffectType
{
wchar_t *displayName; wchar_t *displayName;
// Because I'm lazy, can only have ASCII characters and no spaces. // Because I'm lazy, can only have ASCII characters and no spaces.
wchar_t *effectID; wchar_t *effectID;
@ -173,7 +179,8 @@ struct ForceFeedbackEffectType {
}; };
struct ForceFeedbackAxis { struct ForceFeedbackAxis
{
wchar_t *displayName; wchar_t *displayName;
int id; int id;
}; };
@ -184,7 +191,8 @@ struct ForceFeedbackAxis {
// one set of generic devices. Then I enumerate all devices. Then I merge // one set of generic devices. Then I enumerate all devices. Then I merge
// them, moving settings from the generic devices to the enumerated ones. // them, moving settings from the generic devices to the enumerated ones.
struct PadBindings { struct PadBindings
{
Binding *bindings; Binding *bindings;
int numBindings; int numBindings;
ForceFeedbackBinding *ffBindings; ForceFeedbackBinding *ffBindings;
@ -193,7 +201,8 @@ struct PadBindings {
class WndProcEater; class WndProcEater;
struct InitInfo { struct InitInfo
{
// 1 when binding key to ignore. // 1 when binding key to ignore.
int bindingIgnore; int bindingIgnore;
// 1 when binding. // 1 when binding.
@ -216,7 +225,8 @@ struct InitInfo {
// Mostly self-contained, but bindings are modified by config.cpp, to make // Mostly self-contained, but bindings are modified by config.cpp, to make
// updating the ListView simpler. // updating the ListView simpler.
class Device { class Device
{
public: public:
DeviceAPI api; DeviceAPI api;
DeviceType type; DeviceType type;
@ -231,10 +241,12 @@ public:
WndProcEater *hWndProc; WndProcEater *hWndProc;
#endif #endif
union { union
{
// Allows for one loop to compare all 3 in order. // Allows for one loop to compare all 3 in order.
wchar_t *IDs[3]; wchar_t *IDs[3];
struct { struct
{
// Same as DisplayName, when not given. Absolutely must be unique. // Same as DisplayName, when not given. Absolutely must be unique.
// Used for loading/saving controls. If matches, all other strings // Used for loading/saving controls. If matches, all other strings
// are ignored, so must be unique. // are ignored, so must be unique.
@ -298,17 +310,20 @@ public:
void CalcVirtualState(); void CalcVirtualState();
virtual int Activate(InitInfo *args) { virtual int Activate(InitInfo *args)
{
return 0; return 0;
} }
inline virtual void Deactivate() { inline virtual void Deactivate()
{
FreeState(); FreeState();
active = 0; active = 0;
} }
// Default update proc. All that's needed for post-based APIs. // Default update proc. All that's needed for post-based APIs.
inline virtual int Update() { inline virtual int Update()
{
return active; return active;
} }
@ -328,7 +343,8 @@ public:
virtual void PostRead(); virtual void PostRead();
}; };
class InputDeviceManager { class InputDeviceManager
{
public: public:
Device **devices; Device **devices;
int numDevices; int numDevices;
@ -362,7 +378,8 @@ public:
void ReleaseInput(); void ReleaseInput();
void DisableDevice(int index); void DisableDevice(int index);
inline void EnableDevice(int i) { inline void EnableDevice(int i)
{
devices[i]->enabled = 1; devices[i]->enabled = 1;
} }

View File

@ -34,7 +34,8 @@ static u8 lastQueuedEvent = 0;
static u8 nextQueuedEvent = 0; static u8 nextQueuedEvent = 0;
static keyEvent queuedEvents[EVENT_QUEUE_LEN]; 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;
@ -70,8 +71,10 @@ void QueueKeyEvent(int key, int event) {
#endif #endif
} }
int GetQueuedKeyEvent(keyEvent *event) { int GetQueuedKeyEvent(keyEvent *event)
if (lastQueuedEvent == nextQueuedEvent) return 0; {
if (lastQueuedEvent == nextQueuedEvent)
return 0;
#ifdef _MSC_VER #ifdef _MSC_VER
EnterCriticalSection(&cSection); EnterCriticalSection(&cSection);
@ -86,7 +89,8 @@ int GetQueuedKeyEvent(keyEvent *event) {
return 1; return 1;
} }
void ClearKeyQueue() { void ClearKeyQueue()
{
lastQueuedEvent = nextQueuedEvent; lastQueuedEvent = nextQueuedEvent;
#ifdef _MSC_VER #ifdef _MSC_VER
if (csInitialized) { if (csInitialized) {

File diff suppressed because it is too large Load Diff

View File

@ -73,14 +73,16 @@ remove 0x10F0 to compute the cmd value
#endif #endif
struct GeneralSettingsBool { struct GeneralSettingsBool
{
const wchar_t *name; const wchar_t *name;
unsigned int ControlId; unsigned int ControlId;
u8 defaultValue; u8 defaultValue;
}; };
// XXX: I try to remove only gui stuff // XXX: I try to remove only gui stuff
void DeleteBinding(int port, int slot, Device *dev, Binding *b) { void DeleteBinding(int port, int slot, Device *dev, Binding *b)
{
fprintf(stderr, "delete binding %d:%d\n", port, slot); fprintf(stderr, "delete binding %d:%d\n", port, slot);
Binding *bindings = dev->pads[port][slot].bindings; Binding *bindings = dev->pads[port][slot].bindings;
int i = b - bindings; int i = b - bindings;
@ -88,27 +90,28 @@ void DeleteBinding(int port, int slot, Device *dev, Binding *b) {
dev->pads[port][slot].numBindings--; dev->pads[port][slot].numBindings--;
} }
void DeleteBinding(int port, int slot, Device *dev, ForceFeedbackBinding *b) { void DeleteBinding(int port, int slot, Device *dev, ForceFeedbackBinding *b)
{
ForceFeedbackBinding *bindings = dev->pads[port][slot].ffBindings; ForceFeedbackBinding *bindings = dev->pads[port][slot].ffBindings;
int i = b - bindings; int i = b - bindings;
memmove(bindings + i, bindings + i + 1, sizeof(Binding) * (dev->pads[port][slot].numFFBindings - i - 1)); memmove(bindings + i, bindings + i + 1, sizeof(Binding) * (dev->pads[port][slot].numFFBindings - i - 1));
dev->pads[port][slot].numFFBindings--; dev->pads[port][slot].numFFBindings--;
} }
int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int slot, int command, int sensitivity, int turbo, int deadZone) { int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int slot, int command, int sensitivity, int turbo, int deadZone)
{
// Checks needed because I use this directly when loading bindings. // Checks needed because I use this directly when loading bindings.
if (port > 1 || slot > 3) { if (port > 1 || slot > 3) {
return -1; return -1;
} }
if (!sensitivity) sensitivity = BASE_SENSITIVITY; if (!sensitivity)
sensitivity = BASE_SENSITIVITY;
if ((uid >> 16) & (PSHBTN | TGLBTN)) { if ((uid >> 16) & (PSHBTN | TGLBTN)) {
deadZone = 0; deadZone = 0;
} } else if (!deadZone) {
else if (!deadZone) {
if ((uid >> 16) & PRESSURE_BTN) { if ((uid >> 16) & PRESSURE_BTN) {
deadZone = 1; deadZone = 1;
} } else {
else {
deadZone = DEFAULT_DEADZONE; deadZone = DEFAULT_DEADZONE;
} }
} }
@ -117,14 +120,16 @@ int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int s
sensitivity = abs(sensitivity); sensitivity = abs(sensitivity);
} }
VirtualControl *c = dev->GetVirtualControl(uid); VirtualControl *c = dev->GetVirtualControl(uid);
if (!c) return -1; if (!c)
return -1;
// Add before deleting. Means I won't scroll up one line when scrolled down to bottom. // Add before deleting. Means I won't scroll up one line when scrolled down to bottom.
int controlIndex = c - dev->virtualControls; int controlIndex = c - dev->virtualControls;
int index = 0; int index = 0;
PadBindings *p = dev->pads[port] + slot; PadBindings *p = dev->pads[port] + slot;
p->bindings = (Binding *)realloc(p->bindings, (p->numBindings + 1) * sizeof(Binding)); p->bindings = (Binding *)realloc(p->bindings, (p->numBindings + 1) * sizeof(Binding));
for (index = p->numBindings; index > 0; index--) { for (index = p->numBindings; index > 0; index--) {
if (p->bindings[index-1].controlIndex < controlIndex) break; if (p->bindings[index - 1].controlIndex < controlIndex)
break;
p->bindings[index] = p->bindings[index - 1]; p->bindings[index] = p->bindings[index - 1];
} }
Binding *b = p->bindings + index; Binding *b = p->bindings + index;
@ -149,8 +154,7 @@ int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int s
if (config.multipleBinding) { if (config.multipleBinding) {
if (b->controlIndex == controlIndex && b->command == command) if (b->controlIndex == controlIndex && b->command == command)
nuke = 1; nuke = 1;
} } else {
else {
int uid2 = dev->virtualControls[b->controlIndex].uid; int uid2 = dev->virtualControls[b->controlIndex].uid;
if (b->controlIndex == controlIndex || (!((uid2 ^ uid) & 0xFFFFFF) && ((uid | uid2) & (UID_POV | UID_AXIS)))) if (b->controlIndex == controlIndex || (!((uid2 ^ uid) & 0xFFFFFF) && ((uid | uid2) & (UID_POV | UID_AXIS))))
nuke = 1; nuke = 1;
@ -168,7 +172,8 @@ int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int s
if (!config.multipleBinding) { if (!config.multipleBinding) {
for (int port2 = 0; port2 < 2; port2++) { for (int port2 = 0; port2 < 2; port2++) {
for (int slot2 = 0; slot2 < 4; slot2++) { for (int slot2 = 0; slot2 < 4; slot2++) {
if (port2==(int)port && slot2 == (int)slot) continue; if (port2 == (int)port && slot2 == (int)slot)
continue;
PadBindings *p = dev->pads[port2] + slot2; PadBindings *p = dev->pads[port2] + slot2;
for (int i = 0; i < p->numBindings; i++) { for (int i = 0; i < p->numBindings; i++) {
Binding *b = p->bindings + i; Binding *b = p->bindings + i;
@ -215,7 +220,8 @@ void CALLBACK PADsetSettingsDir( const char *dir )
CfgHelper::SetSettingsDir(dir); CfgHelper::SetSettingsDir(dir);
} }
int SaveSettings(wchar_t *file=0) { int SaveSettings(wchar_t *file = 0)
{
CfgHelper cfg; CfgHelper cfg;
for (size_t i = 0; i < sizeof(BoolOptionsInfo) / sizeof(BoolOptionsInfo[0]); i++) { for (size_t i = 0; i < sizeof(BoolOptionsInfo) / sizeof(BoolOptionsInfo[0]); i++) {
@ -246,9 +252,11 @@ int SaveSettings(wchar_t *file=0) {
wchar_t *name = dev->displayName; wchar_t *name = dev->displayName;
while (name[0] == '[') { while (name[0] == '[') {
wchar_t *name2 = wcschr(name, ']'); wchar_t *name2 = wcschr(name, ']');
if (!name2) break; if (!name2)
break;
name = name2 + 1; name = name2 + 1;
while (iswspace(name[0])) name++; while (iswspace(name[0]))
name++;
} }
cfg.WriteStr(id, L"Display Name", name); cfg.WriteStr(id, L"Display Name", name);
@ -291,8 +299,10 @@ int SaveSettings(wchar_t *file=0) {
return 0; return 0;
} }
int LoadSettings(int force, wchar_t *file) { int LoadSettings(int force, wchar_t *file)
if (dm && !force) return 0; {
if (dm && !force)
return 0;
// Could just do ClearDevices() instead, but if I ever add any extra stuff, // Could just do ClearDevices() instead, but if I ever add any extra stuff,
// this will still work. // this will still work.
@ -307,10 +317,12 @@ int LoadSettings(int force, wchar_t *file) {
config.closeHacks = (u8)cfg.ReadInt(L"General Settings", L"Close Hacks"); config.closeHacks = (u8)cfg.ReadInt(L"General Settings", L"Close Hacks");
if (config.closeHacks&1) config.closeHacks &= ~2; if (config.closeHacks & 1)
config.closeHacks &= ~2;
config.keyboardApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Keyboard Mode", LNX_KEYBOARD); config.keyboardApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Keyboard Mode", LNX_KEYBOARD);
if (!config.keyboardApi) config.keyboardApi = LNX_KEYBOARD; if (!config.keyboardApi)
config.keyboardApi = LNX_KEYBOARD;
config.mouseApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Mouse Mode"); config.mouseApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Mouse Mode");
for (int port = 0; port < 2; port++) { for (int port = 0; port < 2; port++) {
@ -332,7 +344,8 @@ int LoadSettings(int force, wchar_t *file) {
wsprintfW(id, L"Device %i", i++); wsprintfW(id, L"Device %i", i++);
if (!cfg.ReadStr(id, L"Display Name", temp2) || !temp2[0] || if (!cfg.ReadStr(id, L"Display Name", temp2) || !temp2[0] ||
!cfg.ReadStr(id, L"Instance ID", temp3) || !temp3[0]) { !cfg.ReadStr(id, L"Instance ID", temp3) || !temp3[0]) {
if (i >= 100) break; if (i >= 100)
break;
continue; continue;
} }
wchar_t *id2 = 0; wchar_t *id2 = 0;
@ -341,7 +354,8 @@ int LoadSettings(int force, wchar_t *file) {
int api = cfg.ReadInt(id, L"API"); int api = cfg.ReadInt(id, L"API");
int type = cfg.ReadInt(id, L"Type"); int type = cfg.ReadInt(id, L"Type");
if (!api || !type) continue; if (!api || !type)
continue;
Device *dev = new Device((DeviceAPI)api, (DeviceType)type, temp2, temp3, id2); Device *dev = new Device((DeviceAPI)api, (DeviceType)type, temp2, temp3, id2);
dev->attached = 0; dev->attached = 0;
@ -352,7 +366,8 @@ int LoadSettings(int force, wchar_t *file) {
wsprintfW(temp, L"Binding %i", j++); wsprintfW(temp, L"Binding %i", j++);
if (!cfg.ReadStr(id, temp, temp2)) { if (!cfg.ReadStr(id, temp, temp2)) {
if (j >= 100) { if (j >= 100) {
if (!last) break; if (!last)
break;
last = 0; last = 0;
} }
continue; continue;
@ -370,7 +385,8 @@ int LoadSettings(int force, wchar_t *file) {
int len = sscanf(string, " %u , %i , %i , %i , %i , %i , %i", &uid, &port, &command, &sensitivity, &turbo, &slot, &deadZone); int len = sscanf(string, " %u , %i , %i , %i , %i , %i , %i", &uid, &port, &command, &sensitivity, &turbo, &slot, &deadZone);
if (len >= 5 && type) { if (len >= 5 && type) {
VirtualControl *c = dev->GetVirtualControl(uid); VirtualControl *c = dev->GetVirtualControl(uid);
if (!c) c = dev->AddVirtualControl(uid, -1); if (!c)
c = dev->AddVirtualControl(uid, -1);
if (c) { if (c) {
BindCommand(dev, uid, port, slot, command, sensitivity, turbo, deadZone); BindCommand(dev, uid, port, slot, command, sensitivity, turbo, deadZone);
} }
@ -381,7 +397,8 @@ int LoadSettings(int force, wchar_t *file) {
wsprintfW(temp, L"FF Binding %i", j++); wsprintfW(temp, L"FF Binding %i", j++);
if (!cfg.ReadStr(id, temp, temp2)) { if (!cfg.ReadStr(id, temp, temp2)) {
if (j >= 10) { if (j >= 10) {
if (!last) break; if (!last)
break;
last = 0; last = 0;
} }
continue; continue;
@ -400,7 +417,8 @@ int LoadSettings(int force, wchar_t *file) {
// whitespace without it. // whitespace without it.
if (sscanf(string, " %s %i , %i , %i", effect, &port, &motor, &slot) == 4) { if (sscanf(string, " %s %i , %i , %i", effect, &port, &motor, &slot) == 4) {
char *s = strchr(strchr(strchr(string, ',') + 1, ',') + 1, ','); char *s = strchr(strchr(strchr(string, ',') + 1, ',') + 1, ',');
if (!s) continue; if (!s)
continue;
s++; s++;
w = 0; w = 0;
while (effect[w]) { while (effect[w]) {
@ -448,14 +466,16 @@ int LoadSettings(int force, wchar_t *file) {
return 0; return 0;
} }
void UnloadConfigs() { void UnloadConfigs()
{
if (dm) { if (dm) {
delete dm; delete dm;
dm = 0; dm = 0;
} }
} }
void RefreshEnabledDevices(int updateDeviceList) { void RefreshEnabledDevices(int updateDeviceList)
{
// Clears all device state. // Clears all device state.
static int lastXInputState = -1; static int lastXInputState = -1;
if (updateDeviceList || lastXInputState != config.gameApis.xInput) { if (updateDeviceList || lastXInputState != config.gameApis.xInput) {
@ -499,7 +519,8 @@ void RefreshEnabledDevices(int updateDeviceList) {
} }
} }
void Configure() { void Configure()
{
// Can end up here without PADinit() being called first. // Can end up here without PADinit() being called first.
LoadSettings(); LoadSettings();
// Can also end up here after running emulator a bit, and possibly // Can also end up here after running emulator a bit, and possibly

View File

@ -22,7 +22,8 @@
extern void CfgSetSettingsDir(const char *dir); extern void CfgSetSettingsDir(const char *dir);
class CfgHelper { class CfgHelper
{
wxFileConfig *m_config; wxFileConfig *m_config;
static wxString m_path; static wxString m_path;
@ -44,5 +45,4 @@ class CfgHelper {
float ReadFloat(const wchar_t *Section, const wchar_t *Name, float Default = 0.0f); float ReadFloat(const wchar_t *Section, const wchar_t *Name, float Default = 0.0f);
static void SetSettingsDir(const char *dir); static void SetSettingsDir(const char *dir);
}; };

View File

@ -20,7 +20,10 @@
#include "Linux/JoyEvdev.h" #include "Linux/JoyEvdev.h"
#include "Linux/bitmaskros.h" #include "Linux/bitmaskros.h"
JoyEvdev::JoyEvdev(int fd, bool ds3, const wchar_t *id) : Device(LNX_JOY, OTHER, id, id), m_fd(fd) { JoyEvdev::JoyEvdev(int fd, bool ds3, const wchar_t *id)
: Device(LNX_JOY, OTHER, id, id)
, m_fd(fd)
{
// XXX LNX_JOY => DS3 or ??? // XXX LNX_JOY => DS3 or ???
m_abs.clear(); m_abs.clear();
@ -91,11 +94,13 @@ JoyEvdev::JoyEvdev(int fd, bool ds3, const wchar_t *id) : Device(LNX_JOY, OTHER,
fprintf(stderr, "New device created. Found axe:%zu, buttons:%zu, m_rel:%zu\n\n", m_abs.size(), m_btn.size(), m_rel.size()); fprintf(stderr, "New device created. Found axe:%zu, buttons:%zu, m_rel:%zu\n\n", m_abs.size(), m_btn.size(), m_rel.size());
} }
JoyEvdev::~JoyEvdev() { JoyEvdev::~JoyEvdev()
{
close(m_fd); close(m_fd);
} }
int JoyEvdev::Activate(InitInfo* args) { int JoyEvdev::Activate(InitInfo *args)
{
AllocState(); AllocState();
uint16_t size = m_abs.size() + m_rel.size() + m_btn.size(); uint16_t size = m_abs.size() + m_rel.size() + m_btn.size();
@ -105,7 +110,8 @@ int JoyEvdev::Activate(InitInfo* args) {
return 1; return 1;
} }
int JoyEvdev::Update() { int JoyEvdev::Update()
{
struct input_event events[32]; struct input_event events[32];
int len; int len;
int status = 0; int status = 0;
@ -117,8 +123,7 @@ int JoyEvdev::Update() {
//fprintf(stderr, "Poll %d events available\n", evt_nb); //fprintf(stderr, "Poll %d events available\n", evt_nb);
for (int i = 0; i < evt_nb; i++) { for (int i = 0; i < evt_nb; i++) {
switch (events[i].type) { switch (events[i].type) {
case EV_ABS: case EV_ABS: {
{
for (size_t idx = 0; idx < m_abs.size(); idx++) { for (size_t idx = 0; idx < m_abs.size(); idx++) {
if (m_abs[idx].code == events[i].code) { if (m_abs[idx].code == events[i].code) {
// XXX strict or not ? // XXX strict or not ?
@ -131,10 +136,8 @@ int JoyEvdev::Update() {
} }
} }
} }
} } break;
break; case EV_KEY: {
case EV_KEY:
{
for (size_t idx = 0; idx < m_btn.size(); idx++) { for (size_t idx = 0; idx < m_btn.size(); idx++) {
if (m_btn[idx] == events[i].code) { if (m_btn[idx] == events[i].code) {
fprintf(stderr, "Event KEY:%d detected with value %d\n", events[i].code, events[i].value); fprintf(stderr, "Event KEY:%d detected with value %d\n", events[i].code, events[i].value);
@ -144,8 +147,7 @@ int JoyEvdev::Update() {
} }
} }
} } break;
break;
case EV_REL: case EV_REL:
// XXX // XXX
break; break;
@ -153,14 +155,14 @@ int JoyEvdev::Update() {
break; break;
} }
} }
} }
return status; return status;
} }
static std::wstring CorrectJoySupport(int fd) { static std::wstring CorrectJoySupport(int fd)
{
struct input_id id; struct input_id id;
if (ioctl(fd, EVIOCGID, &id) < 0) { if (ioctl(fd, EVIOCGID, &id) < 0) {
fprintf(stderr, "Invalid IOCTL EVIOCGID\n"); fprintf(stderr, "Invalid IOCTL EVIOCGID\n");
@ -180,7 +182,8 @@ static std::wstring CorrectJoySupport(int fd) {
return std::wstring(s.begin(), s.end()); return std::wstring(s.begin(), s.end());
} }
void EnumJoystickEvdev() { void EnumJoystickEvdev()
{
// Technically it must be done with udev but another lib for // Technically it must be done with udev but another lib for
// avoid a loop is too much for me (even if udev is mandatory // avoid a loop is too much for me (even if udev is mandatory
// so maybe later) // so maybe later)
@ -204,5 +207,4 @@ void EnumJoystickEvdev() {
} else if (fd >= 0) } else if (fd >= 0)
close(fd); close(fd);
} }
} }

View File

@ -23,7 +23,8 @@
#include <fcntl.h> #include <fcntl.h>
#include <linux/input.h> #include <linux/input.h>
struct abs_info { struct abs_info
{
uint16_t code; uint16_t code;
int32_t min; int32_t min;
int32_t max; int32_t max;
@ -31,7 +32,11 @@ struct abs_info {
int32_t factor; int32_t factor;
int32_t translation; int32_t translation;
abs_info(int32_t _code, int32_t _min, int32_t _max, ControlType type) : code(_code), min(_min), max(_max) { abs_info(int32_t _code, int32_t _min, int32_t _max, ControlType type)
: code(_code)
, min(_min)
, max(_max)
{
translation = 0; translation = 0;
// Note: ABSAXIS ranges from -64K to 64K // Note: ABSAXIS ranges from -64K to 64K
// Note: PSHBTN ranges from 0 to 64K // Note: PSHBTN ranges from 0 to 64K
@ -56,12 +61,14 @@ struct abs_info {
} }
} }
int scale(int32_t value) { int scale(int32_t value)
{
return (value - translation) * factor; return (value - translation) * factor;
} }
}; };
class JoyEvdev : public Device { class JoyEvdev : public Device
{
int m_fd; int m_fd;
std::vector<abs_info> m_abs; std::vector<abs_info> m_abs;
std::vector<uint16_t> m_btn; std::vector<uint16_t> m_btn;

View File

@ -20,15 +20,16 @@
// actually it is even more but it is enough to distinguish different key // actually it is even more but it is enough to distinguish different key
#define MAX_KEYCODE (0xFF) #define MAX_KEYCODE (0xFF)
LinuxKeyboard::LinuxKeyboard() : LinuxKeyboard::LinuxKeyboard()
Device(LNX_KEYBOARD, KEYBOARD, L"displayName", L"instanceID", L"deviceID") : Device(LNX_KEYBOARD, KEYBOARD, L"displayName", L"instanceID", L"deviceID")
{ {
for (int i = 0; i < MAX_KEYCODE; i++) { for (int i = 0; i < MAX_KEYCODE; i++) {
AddPhysicalControl(PSHBTN, i, i); AddPhysicalControl(PSHBTN, i, i);
} }
} }
int LinuxKeyboard::Activate(InitInfo* args) { int LinuxKeyboard::Activate(InitInfo *args)
{
// Always active // Always active
active = 1; active = 1;
@ -50,7 +51,8 @@ int LinuxKeyboard::Activate(InitInfo* args) {
return 1; return 1;
} }
int LinuxKeyboard::Update() { int LinuxKeyboard::Update()
{
keyEvent event; keyEvent event;
int status = 0; int status = 0;
while (R_GetQueuedKeyEvent(&event)) { while (R_GetQueuedKeyEvent(&event)) {
@ -73,6 +75,7 @@ int LinuxKeyboard::Update() {
return status; // XXX ???? return status; // XXX ????
} }
void EnumLnx() { void EnumLnx()
{
dm->AddDevice(new LinuxKeyboard()); dm->AddDevice(new LinuxKeyboard());
} }

View File

@ -19,7 +19,8 @@
#include "InputManager.h" #include "InputManager.h"
#include "KeyboardQueue.h" #include "KeyboardQueue.h"
class LinuxKeyboard : public Device { class LinuxKeyboard : public Device
{
public: public:
LinuxKeyboard(); LinuxKeyboard();
int Activate(InitInfo *args); int Activate(InitInfo *args);

View File

@ -32,7 +32,8 @@ static u8 R_lastQueuedEvent = 0;
static u8 R_nextQueuedEvent = 0; static u8 R_nextQueuedEvent = 0;
static keyEvent R_queuedEvents[R_EVENT_QUEUE_LEN]; static keyEvent R_queuedEvents[R_EVENT_QUEUE_LEN];
void R_QueueKeyEvent(const keyEvent &evt) { void R_QueueKeyEvent(const keyEvent &evt)
{
std::lock_guard<std::mutex> lock(core_event); std::lock_guard<std::mutex> lock(core_event);
R_queuedEvents[R_lastQueuedEvent] = evt; R_queuedEvents[R_lastQueuedEvent] = evt;
@ -41,8 +42,10 @@ void R_QueueKeyEvent(const keyEvent &evt) {
assert(R_nextQueuedEvent != R_lastQueuedEvent); assert(R_nextQueuedEvent != R_lastQueuedEvent);
} }
int R_GetQueuedKeyEvent(keyEvent *event) { int R_GetQueuedKeyEvent(keyEvent *event)
if (R_lastQueuedEvent == R_nextQueuedEvent) return 0; {
if (R_lastQueuedEvent == R_nextQueuedEvent)
return 0;
std::lock_guard<std::mutex> lock(core_event); std::lock_guard<std::mutex> lock(core_event);
*event = R_queuedEvents[R_nextQueuedEvent]; *event = R_queuedEvents[R_nextQueuedEvent];
@ -50,11 +53,13 @@ int R_GetQueuedKeyEvent(keyEvent *event) {
return 1; return 1;
} }
void R_ClearKeyQueue() { void R_ClearKeyQueue()
{
R_lastQueuedEvent = R_nextQueuedEvent; R_lastQueuedEvent = R_nextQueuedEvent;
} }
EXPORT_C_(void) PADWriteEvent(keyEvent &evt) EXPORT_C_(void)
PADWriteEvent(keyEvent &evt)
{ {
R_QueueKeyEvent(evt); R_QueueKeyEvent(evt);
} }

View File

@ -26,7 +26,8 @@
ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output); ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
int GetRawKeyboards(HWND hWnd) { int GetRawKeyboards(HWND hWnd)
{
RAWINPUTDEVICE Rid; RAWINPUTDEVICE Rid;
Rid.hwndTarget = hWnd; Rid.hwndTarget = hWnd;
@ -36,7 +37,8 @@ int GetRawKeyboards(HWND hWnd) {
return RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); return RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
} }
void ReleaseRawKeyboards() { void ReleaseRawKeyboards()
{
RAWINPUTDEVICE Rid; RAWINPUTDEVICE Rid;
Rid.hwndTarget = 0; Rid.hwndTarget = 0;
@ -46,7 +48,8 @@ void ReleaseRawKeyboards() {
RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
} }
int GetRawMice(HWND hWnd) { int GetRawMice(HWND hWnd)
{
RAWINPUTDEVICE Rid; RAWINPUTDEVICE Rid;
Rid.hwndTarget = hWnd; Rid.hwndTarget = hWnd;
@ -56,7 +59,8 @@ int GetRawMice(HWND hWnd) {
return RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); return RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
} }
void ReleaseRawMice() { void ReleaseRawMice()
{
RAWINPUTDEVICE Rid; RAWINPUTDEVICE Rid;
Rid.hwndTarget = 0; Rid.hwndTarget = 0;
@ -72,15 +76,19 @@ static int rawKeyboardActivatedCount = 0;
// Same for mice. // Same for mice.
static int rawMouseActivatedCount = 0; static int rawMouseActivatedCount = 0;
class RawInputKeyboard : public WindowsKeyboard { class RawInputKeyboard : public WindowsKeyboard
{
public: public:
HANDLE hDevice; HANDLE hDevice;
RawInputKeyboard(HANDLE hDevice, wchar_t *name, wchar_t *instanceID=0) : WindowsKeyboard(RAW, name, instanceID) { RawInputKeyboard(HANDLE hDevice, wchar_t *name, wchar_t *instanceID = 0)
: WindowsKeyboard(RAW, name, instanceID)
{
this->hDevice = hDevice; this->hDevice = hDevice;
} }
int Activate(InitInfo *initInfo) { int Activate(InitInfo *initInfo)
{
Deactivate(); Deactivate();
hWndProc = initInfo->hWndProc; hWndProc = initInfo->hWndProc;
@ -100,7 +108,8 @@ public:
return 1; return 1;
} }
void Deactivate() { void Deactivate()
{
FreeState(); FreeState();
if (active) { if (active) {
active = 0; active = 0;
@ -114,15 +123,19 @@ public:
} }
}; };
class RawInputMouse : public WindowsMouse { class RawInputMouse : public WindowsMouse
{
public: public:
HANDLE hDevice; HANDLE hDevice;
RawInputMouse(HANDLE hDevice, wchar_t *name, wchar_t *instanceID=0, wchar_t *productID=0) : WindowsMouse(RAW, 0, name, instanceID, productID) { RawInputMouse(HANDLE hDevice, wchar_t *name, wchar_t *instanceID = 0, wchar_t *productID = 0)
: WindowsMouse(RAW, 0, name, instanceID, productID)
{
this->hDevice = hDevice; this->hDevice = hDevice;
} }
int Activate(InitInfo *initInfo) { int Activate(InitInfo *initInfo)
{
Deactivate(); Deactivate();
hWndProc = initInfo->hWndProc; hWndProc = initInfo->hWndProc;
@ -147,7 +160,8 @@ public:
return 1; return 1;
} }
void Deactivate() { void Deactivate()
{
FreeState(); FreeState();
if (active) { if (active) {
active = 0; active = 0;
@ -163,7 +177,8 @@ 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;
@ -171,18 +186,20 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
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) continue; if (dev->api != RAW || !dev->active)
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) continue; if (rik->hDevice != in.header.hDevice)
continue;
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) continue; if (rim->hDevice != in.header.hDevice)
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
@ -212,15 +229,14 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
} }
} }
} }
} } else if (uMsg == WM_ACTIVATE) {
else if (uMsg == WM_ACTIVATE) {
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->physicalControlState == 0) continue; if (dev->api != RAW || dev->physicalControlState == 0)
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);
} }
@ -228,7 +244,8 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
return CONTINUE_BLISSFULLY; return CONTINUE_BLISSFULLY;
} }
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));
@ -244,7 +261,8 @@ void EnumRawInputDevices() {
// 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) continue; if (list[i].dwType != RIM_TYPEKEYBOARD && list[i].dwType != RIM_TYPEMOUSE)
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);
@ -258,16 +276,19 @@ void EnumRawInputDevices() {
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) break; if (!s)
break;
*s = '\\'; *s = '\\';
if (j == 2) { if (j == 2) {
*s = 0; *s = 0;
} }
if (j==1) temp = s; if (j == 1)
temp = s;
} }
wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID + 3); wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID + 3);
if (temp) *temp = 0; if (temp)
*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)) {
@ -276,8 +297,10 @@ void EnumRawInputDevices() {
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) temp2 = displayName; if (!temp2)
else temp2++; temp2 = displayName;
else
temp2++;
// Could do without this, but more effort than it's worth. // Could do without this, but more effort than it's worth.
wcscpy(keyName, temp2); wcscpy(keyName, temp2);
haveDescription = 1; haveDescription = 1;
@ -285,13 +308,16 @@ void EnumRawInputDevices() {
RegCloseKey(hKey); RegCloseKey(hKey);
} }
if (list[i].dwType == RIM_TYPEKEYBOARD) { if (list[i].dwType == RIM_TYPEKEYBOARD) {
if (!haveDescription) wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++); if (!haveDescription)
else wsprintfW(displayName, L"Raw KB: %s", keyName); wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++);
else
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 wsprintfW(displayName, L"Raw MS: %s", keyName); else
wsprintfW(displayName, L"Raw MS: %s", keyName);
dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID)); dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID));
} }
} }

View File

@ -18,12 +18,15 @@
#include "Global.h" #include "Global.h"
#include "VKey.h" #include "VKey.h"
wchar_t *GetVKStringW(unsigned char vk) { 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: return L"Clear"; case 0x0C:
case 0x13: return L"Pause"; return L"Clear";
case 0x13:
return L"Pause";
case 0x21: // return "Page Up"; case 0x21: // return "Page Up";
case 0x22: // return "Page Down"; case 0x22: // return "Page Down";
@ -42,32 +45,54 @@ wchar_t *GetVKStringW(unsigned char vk) {
flag = 1 << 24; flag = 1 << 24;
break; break;
case 0x29: return L"Select"; case 0x29:
case 0x2A: return L"Print"; return L"Select";
case 0x2B: return L"Execute"; case 0x2A:
case 0x2C: return L"Prnt Scrn"; return L"Print";
case 0x2F: return L"Help"; case 0x2B:
return L"Execute";
case 0x2C:
return L"Prnt Scrn";
case 0x2F:
return L"Help";
case 0x6C: return L"|"; case 0x6C:
case 0x90: return L"Num Lock"; return L"|";
case 0x90:
return L"Num Lock";
case 0xA0: return L"Left Shift"; case 0xA0:
case 0xA1: return L"Right Shift"; return L"Left Shift";
case 0xA2: return L"Left Ctrl"; case 0xA1:
case 0xA3: return L"Right Ctrl"; return L"Right Shift";
case 0xA4: return L"Left Alt"; case 0xA2:
case 0xA5: return L"Right Alt"; return L"Left Ctrl";
case 0xA3:
return L"Right Ctrl";
case 0xA4:
return L"Left Alt";
case 0xA5:
return L"Right Alt";
case 0xA6: return L"Back"; case 0xA6:
case 0xA7: return L"Forward"; return L"Back";
case 0xA8: return L"Refresh"; case 0xA7:
case 0xA9: return L"Stop"; return L"Forward";
case 0xAA: return L"Search"; case 0xA8:
case 0xAB: return L"Favorites"; return L"Refresh";
case 0xAC: return L"Browser"; case 0xA9:
return L"Stop";
case 0xAA:
return L"Search";
case 0xAB:
return L"Favorites";
case 0xAC:
return L"Browser";
case 0xFA: return L"Play"; case 0xFA:
case 0xFB: return L"Zoom"; return L"Play";
case 0xFB:
return L"Zoom";
default: default:
flag = 0; flag = 0;
break; break;
@ -76,10 +101,8 @@ wchar_t *GetVKStringW(unsigned char vk) {
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

@ -21,30 +21,35 @@
#include "WindowsKeyboard.h" #include "WindowsKeyboard.h"
#include "KeyboardQueue.h" #include "KeyboardQueue.h"
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);
} }
} }
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) return w; if (w)
return w;
} }
return Device::GetPhysicalControlName(control); return Device::GetPhysicalControlName(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) event = KEYRELEASE; if (!newState)
event = KEYRELEASE;
QueueKeyEvent(vkey, event); QueueKeyEvent(vkey, event);
} }
} }
@ -52,7 +57,8 @@ 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);

View File

@ -16,7 +16,8 @@
*/ */
// Shared functionality for WM and RAW keyboards. // Shared functionality for WM and RAW keyboards.
class WindowsKeyboard : public Device { class WindowsKeyboard : public Device
{
public: public:
WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID = 0, wchar_t *deviceID = 0); WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID = 0, wchar_t *deviceID = 0);
wchar_t *GetPhysicalControlName(PhysicalControl *control); wchar_t *GetPhysicalControlName(PhysicalControl *control);

View File

@ -32,16 +32,20 @@ class WindowsMessagingMouse;
static WindowsMessagingKeyboard *wmk = 0; static WindowsMessagingKeyboard *wmk = 0;
static WindowsMessagingMouse *wmm = 0; static WindowsMessagingMouse *wmm = 0;
class WindowsMessagingKeyboard : public WindowsKeyboard { class WindowsMessagingKeyboard : public WindowsKeyboard
{
public: public:
WindowsMessagingKeyboard()
WindowsMessagingKeyboard() : WindowsKeyboard(WM, L"WM Keyboard") { : WindowsKeyboard(WM, L"WM Keyboard")
{
} }
int Activate(InitInfo *initInfo) { int Activate(InitInfo *initInfo)
{
// Redundant. Should match the next line. // Redundant. Should match the next line.
// Deactivate(); // Deactivate();
if (wmk) wmk->Deactivate(); if (wmk)
wmk->Deactivate();
hWndProc = initInfo->hWndProc; hWndProc = initInfo->hWndProc;
@ -55,7 +59,8 @@ public:
return 1; return 1;
} }
void Deactivate() { void Deactivate()
{
if (active) { if (active) {
if (!wmm) if (!wmm)
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
@ -66,21 +71,26 @@ public:
} }
void CheckKey(int vkey) { void CheckKey(int vkey)
{
UpdateKey(vkey, 1 & (((unsigned short)GetAsyncKeyState(vkey)) >> 15)); UpdateKey(vkey, 1 & (((unsigned short)GetAsyncKeyState(vkey)) >> 15));
} }
}; };
class WindowsMessagingMouse : public WindowsMouse { class WindowsMessagingMouse : public WindowsMouse
{
public: public:
WindowsMessagingMouse()
WindowsMessagingMouse() : WindowsMouse(WM, 1, L"WM Mouse") { : WindowsMouse(WM, 1, L"WM Mouse")
{
} }
int Activate(InitInfo *initInfo) { int Activate(InitInfo *initInfo)
{
// Redundant. Should match the next line. // Redundant. Should match the next line.
// Deactivate(); // Deactivate();
if (wmm) wmm->Deactivate(); if (wmm)
wmm->Deactivate();
hWndProc = initInfo->hWndProc; hWndProc = initInfo->hWndProc;
if (!wmk) if (!wmk)
@ -96,7 +106,8 @@ public:
return 1; return 1;
} }
void Deactivate() { void Deactivate()
{
if (active) { if (active) {
if (!wmk) if (!wmk)
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
@ -108,30 +119,27 @@ 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 (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) {
if (wParam == VK_SHIFT) { 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);
} }
@ -148,32 +156,25 @@ ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam,
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.
@ -185,7 +186,8 @@ ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam,
return CONTINUE_BLISSFULLY; return CONTINUE_BLISSFULLY;
} }
void EnumWindowsMessagingDevices() { void EnumWindowsMessagingDevices()
{
dm->AddDevice(new WindowsMessagingKeyboard()); dm->AddDevice(new WindowsMessagingKeyboard());
dm->AddDevice(new WindowsMessagingMouse()); dm->AddDevice(new WindowsMessagingMouse());
} }

View File

@ -23,8 +23,9 @@
POINT WindowsMouse::origCursorPos; POINT WindowsMouse::origCursorPos;
POINT WindowsMouse::center; POINT WindowsMouse::center;
WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) : WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID)
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);
@ -35,7 +36,8 @@ Device(api, MOUSE, displayName, instanceID, deviceID) {
} }
} }
wchar_t *WindowsMouse::GetPhysicalControlName(PhysicalControl *control) { wchar_t *WindowsMouse::GetPhysicalControlName(PhysicalControl *control)
{
wchar_t *names[9] = { wchar_t *names[9] = {
L"L Button", L"L Button",
L"R Button", L"R Button",
@ -45,24 +47,29 @@ wchar_t *WindowsMouse::GetPhysicalControlName(PhysicalControl *control) {
L"X Axis", L"X Axis",
L"Y Axis", L"Y Axis",
L"Y Wheel", L"Y Wheel",
L"X Wheel" L"X Wheel"};
}; if (control->id < 9)
if (control->id < 9) return names[control->id]; return names[control->id];
return Device::GetPhysicalControlName(control); return Device::GetPhysicalControlName(control);
} }
void WindowsMouse::UpdateButton(unsigned int button, int state) { void WindowsMouse::UpdateButton(unsigned int button, int state)
if (button > 4) return; {
if (button > 4)
return;
physicalControlState[button] = (state << 16); physicalControlState[button] = (state << 16);
} }
void WindowsMouse::UpdateAxis(unsigned int axis, int delta) { void WindowsMouse::UpdateAxis(unsigned int axis, int delta)
if (axis > 3) return; {
if (axis > 3)
return;
// 1 mouse pixel = 1/8th way down. // 1 mouse pixel = 1/8th way down.
physicalControlState[5 + axis] += (delta << (16 - 3 * (axis < 2))); physicalControlState[5 + axis] += (delta << (16 - 3 * (axis < 2)));
} }
void WindowsMouse::WindowResized(HWND hWnd) { void WindowsMouse::WindowResized(HWND hWnd)
{
RECT r; RECT r;
GetWindowRect(hWnd, &r); GetWindowRect(hWnd, &r);
ClipCursor(&r); ClipCursor(&r);
@ -71,7 +78,8 @@ void WindowsMouse::WindowResized(HWND hWnd) {
SetCursorPos(center.x, center.y); SetCursorPos(center.x, center.y);
} }
void WindowsMouse::GetMouseCapture(HWND hWnd) { void WindowsMouse::GetMouseCapture(HWND hWnd)
{
SetCapture(hWnd); SetCapture(hWnd);
ShowCursor(0); ShowCursor(0);
@ -85,7 +93,8 @@ void WindowsMouse::GetMouseCapture(HWND hWnd) {
SetCursorPos(center.x, center.y); SetCursorPos(center.x, center.y);
} }
void WindowsMouse::ReleaseMouseCapture() { void WindowsMouse::ReleaseMouseCapture()
{
ClipCursor(0); ClipCursor(0);
ReleaseCapture(); ReleaseCapture();
ShowCursor(1); ShowCursor(1);

View File

@ -16,7 +16,8 @@
*/ */
// Shared functionality for WM and RAW keyboards. // Shared functionality for WM and RAW keyboards.
class WindowsMouse : public Device { class WindowsMouse : public Device
{
public: public:
// Used by GetMouseCapture()/ReleaseMouseCapture() // Used by GetMouseCapture()/ReleaseMouseCapture()
// Static because can have multiple raw mice active at once, // Static because can have multiple raw mice active at once,

View File

@ -37,9 +37,11 @@ WndProcEater::~WndProcEater() throw()
} }
} }
void WndProcEater::ReleaseExtraProc(ExtraWndProc proc) { void WndProcEater::ReleaseExtraProc(ExtraWndProc proc)
{
// Probably isn't needed, but just in case... // Probably isn't needed, but just in case...
if (hMutex) WaitForSingleObject(hMutex, 100); if (hMutex)
WaitForSingleObject(hMutex, 100);
//printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc ); //printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc );
@ -57,8 +59,10 @@ void WndProcEater::ReleaseExtraProc(ExtraWndProc proc) {
} }
} }
void WndProcEater::Release() { void WndProcEater::Release()
while (numExtraProcs) ReleaseExtraProc(extraProcs[0].proc); {
while (numExtraProcs)
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);
@ -90,8 +94,8 @@ LRESULT WndProcEater::_OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
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;
} }
} }
@ -117,7 +121,8 @@ static LRESULT CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
bool WndProcEater::SetWndHandle(HWND hWnd) bool WndProcEater::SetWndHandle(HWND hWnd)
{ {
if(hWnd == hWndEaten) return true; if (hWnd == hWndEaten)
return true;
//printf( "(Lilypad) (Re)-Setting window handle! -> this=0x%08x, hWnd=0x%08x\n", this, hWnd ); //printf( "(Lilypad) (Re)-Setting window handle! -> this=0x%08x, hWnd=0x%08x\n", this, hWnd );
@ -130,13 +135,16 @@ bool WndProcEater::SetWndHandle(HWND hWnd)
return !!hWndEaten; return !!hWndEaten;
} }
void WndProcEater::Eat(ExtraWndProc proc, DWORD flags) { void WndProcEater::Eat(ExtraWndProc proc, DWORD flags)
{
// check if Subclassing failed to init during SetWndHandle // check if Subclassing failed to init during SetWndHandle
if (!hWndEaten) return; if (!hWndEaten)
return;
// Probably isn't needed, but just in case... // Probably isn't needed, but just in case...
if (hMutex) WaitForSingleObject(hMutex, 100); if (hMutex)
WaitForSingleObject(hMutex, 100);
//printf( "(Lilypad) EatingWndProc! -> 0x%x\n", proc ); //printf( "(Lilypad) EatingWndProc! -> 0x%x\n", proc );

View File

@ -29,7 +29,8 @@ enum ExtraWndProcResult {
typedef ExtraWndProcResult (*ExtraWndProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *out); typedef ExtraWndProcResult (*ExtraWndProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *out);
struct ExtraWndProcInfo { struct ExtraWndProcInfo
{
ExtraWndProc proc; ExtraWndProc proc;
DWORD flags; DWORD flags;
}; };

View File

@ -73,24 +73,29 @@ _XInputSetState pXInputSetState = 0;
static int xInputActiveCount = 0; static int xInputActiveCount = 0;
// Completely unncessary, really. // Completely unncessary, really.
__forceinline int ShortToAxis(int v) { __forceinline int ShortToAxis(int v)
{
// If positive and at least 1 << 14, increment. // If positive and at least 1 << 14, increment.
v += (!((v >> 15) & 1)) & ((v >> 14) & 1); v += (!((v >> 15) & 1)) & ((v >> 14) & 1);
// Just double. // Just double.
return v * 2; return v * 2;
} }
class XInputDevice : public Device { class XInputDevice : public Device
{
// Cached last vibration values by pad and motor. // Cached last vibration values by pad and motor.
// Need this, as only one value is changed at a time. // Need this, as only one value is changed at a time.
int ps2Vibration[2][4][2]; int ps2Vibration[2][4][2];
// Minor optimization - cache last set vibration values // Minor optimization - cache last set vibration values
// When there's no change, no need to do anything. // When there's no change, no need to do anything.
XINPUT_VIBRATION xInputVibration; XINPUT_VIBRATION xInputVibration;
public: public:
int index; int index;
XInputDevice(int index, wchar_t *displayName) : Device(XINPUT, OTHER, displayName) { XInputDevice(int index, wchar_t *displayName)
: Device(XINPUT, OTHER, displayName)
{
memset(ps2Vibration, 0, sizeof(ps2Vibration)); memset(ps2Vibration, 0, sizeof(ps2Vibration));
memset(&xInputVibration, 0, sizeof(xInputVibration)); memset(&xInputVibration, 0, sizeof(xInputVibration));
this->index = index; this->index = index;
@ -106,7 +111,8 @@ public:
AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT); AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT);
} }
wchar_t *GetPhysicalControlName(PhysicalControl *c) { wchar_t *GetPhysicalControlName(PhysicalControl *c)
{
const static wchar_t *names[] = { const static wchar_t *names[] = {
L"D-pad Up", L"D-pad Up",
L"D-pad Down", L"D-pad Down",
@ -137,8 +143,10 @@ public:
return Device::GetPhysicalControlName(c); return Device::GetPhysicalControlName(c);
} }
int Activate(InitInfo *initInfo) { int Activate(InitInfo *initInfo)
if (active) Deactivate(); {
if (active)
Deactivate();
if (!xInputActiveCount) { if (!xInputActiveCount) {
pXInputEnable(1); pXInputEnable(1);
} }
@ -148,8 +156,10 @@ public:
return 1; return 1;
} }
int Update() { int Update()
if (!active) return 0; {
if (!active)
return 0;
XINPUT_STATE state; XINPUT_STATE state;
if (ERROR_SUCCESS != pXInputGetStateEx(index, &state)) { if (ERROR_SUCCESS != pXInputGetStateEx(index, &state)) {
Deactivate(); Deactivate();
@ -193,7 +203,8 @@ public:
return 1; return 1;
} }
void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) { void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force)
{
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++) {
@ -222,7 +233,8 @@ public:
} }
} }
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) { void SetEffect(ForceFeedbackBinding *binding, unsigned char force)
{
PadBindings pBackup = pads[0][0]; PadBindings pBackup = pads[0][0];
pads[0][0].ffBindings = binding; pads[0][0].ffBindings = binding;
pads[0][0].numFFBindings = 1; pads[0][0].numFFBindings = 1;
@ -230,7 +242,8 @@ public:
pads[0][0] = pBackup; pads[0][0] = pBackup;
} }
void Deactivate() { void Deactivate()
{
memset(&xInputVibration, 0, sizeof(xInputVibration)); memset(&xInputVibration, 0, sizeof(xInputVibration));
memset(ps2Vibration, 0, sizeof(ps2Vibration)); memset(ps2Vibration, 0, sizeof(ps2Vibration));
pXInputSetState(index, &xInputVibration); pXInputSetState(index, &xInputVibration);
@ -244,16 +257,19 @@ public:
} }
} }
~XInputDevice() { ~XInputDevice()
{
} }
}; };
void EnumXInputDevices() { void EnumXInputDevices()
{
wchar_t temp[30]; wchar_t temp[30];
if (!pXInputSetState) { if (!pXInputSetState) {
// Also used as flag to indicute XInput not installed, so // Also used as flag to indicute XInput not installed, so
// don't repeatedly try to load it. // don't repeatedly try to load it.
if (pXInputEnable) return; if (pXInputEnable)
return;
// Prefer XInput 1.3 since SCP only has an XInput 1.3 wrapper right now. // Prefer XInput 1.3 since SCP only has an XInput 1.3 wrapper right now.
// Also use LoadLibrary and not LoadLibraryEx for XInput 1.3, since some // Also use LoadLibrary and not LoadLibraryEx for XInput 1.3, since some
@ -284,4 +300,3 @@ void EnumXInputDevices() {
} }
pXInputEnable(0); pXInputEnable(0);
} }

View File

@ -97,20 +97,23 @@
/* All standard descriptors have these 2 fields in common */ /* All standard descriptors have these 2 fields in common */
struct usb_descriptor_header { struct usb_descriptor_header
{
unsigned char bLength; unsigned char bLength;
unsigned char bDescriptorType; unsigned char bDescriptorType;
}; };
/* String descriptor */ /* String descriptor */
struct usb_string_descriptor { struct usb_string_descriptor
{
unsigned char bLength; unsigned char bLength;
unsigned char bDescriptorType; unsigned char bDescriptorType;
unsigned short wData[1]; unsigned short wData[1];
}; };
/* HID descriptor */ /* HID descriptor */
struct usb_hid_descriptor { struct usb_hid_descriptor
{
unsigned char bLength; unsigned char bLength;
unsigned char bDescriptorType; unsigned char bDescriptorType;
unsigned short bcdHID; unsigned short bcdHID;
@ -120,7 +123,8 @@ struct usb_hid_descriptor {
/* Endpoint descriptor */ /* Endpoint descriptor */
#define USB_MAXENDPOINTS 32 #define USB_MAXENDPOINTS 32
struct usb_endpoint_descriptor { struct usb_endpoint_descriptor
{
unsigned char bLength; unsigned char bLength;
unsigned char bDescriptorType; unsigned char bDescriptorType;
unsigned char bEndpointAddress; unsigned char bEndpointAddress;
@ -145,7 +149,8 @@ struct usb_endpoint_descriptor {
/* Interface descriptor */ /* Interface descriptor */
#define USB_MAXINTERFACES 32 #define USB_MAXINTERFACES 32
struct usb_interface_descriptor { struct usb_interface_descriptor
{
unsigned char bLength; unsigned char bLength;
unsigned char bDescriptorType; unsigned char bDescriptorType;
unsigned char bInterfaceNumber; unsigned char bInterfaceNumber;
@ -164,7 +169,8 @@ struct usb_interface_descriptor {
#define USB_MAXALTSETTING 128 /* Hard limit */ #define USB_MAXALTSETTING 128 /* Hard limit */
struct usb_interface { struct usb_interface
{
struct usb_interface_descriptor *altsetting; struct usb_interface_descriptor *altsetting;
int num_altsetting; int num_altsetting;
@ -172,7 +178,8 @@ struct usb_interface {
/* Configuration descriptor information.. */ /* Configuration descriptor information.. */
#define USB_MAXCONFIG 8 #define USB_MAXCONFIG 8
struct usb_config_descriptor { struct usb_config_descriptor
{
unsigned char bLength; unsigned char bLength;
unsigned char bDescriptorType; unsigned char bDescriptorType;
unsigned short wTotalLength; unsigned short wTotalLength;
@ -189,7 +196,8 @@ struct usb_config_descriptor {
}; };
/* Device descriptor */ /* Device descriptor */
struct usb_device_descriptor { struct usb_device_descriptor
{
unsigned char bLength; unsigned char bLength;
unsigned char bDescriptorType; unsigned char bDescriptorType;
unsigned short bcdUSB; unsigned short bcdUSB;
@ -206,7 +214,8 @@ struct usb_device_descriptor {
unsigned char bNumConfigurations; unsigned char bNumConfigurations;
}; };
struct usb_ctrl_setup { struct usb_ctrl_setup
{
unsigned char bRequestType; unsigned char bRequestType;
unsigned char bRequest; unsigned char bRequest;
unsigned short wValue; unsigned short wValue;
@ -261,7 +270,8 @@ struct usb_ctrl_setup {
/* struct usb_device; */ /* struct usb_device; */
/* struct usb_bus; */ /* struct usb_bus; */
struct usb_device { struct usb_device
{
struct usb_device *next, *prev; struct usb_device *next, *prev;
char filename[LIBUSB_PATH_MAX]; char filename[LIBUSB_PATH_MAX];
@ -279,7 +289,8 @@ struct usb_device {
struct usb_device **children; struct usb_device **children;
}; };
struct usb_bus { struct usb_bus
{
struct usb_bus *next, *prev; struct usb_bus *next, *prev;
char dirname[LIBUSB_PATH_MAX]; char dirname[LIBUSB_PATH_MAX];
@ -291,14 +302,17 @@ struct usb_bus {
}; };
/* Version information, Windows specific */ /* Version information, Windows specific */
struct usb_version { struct usb_version
struct { {
struct
{
int major; int major;
int minor; int minor;
int micro; int micro;
int nano; int nano;
} dll; } dll;
struct { struct
{
int major; int major;
int minor; int minor;
int micro; int micro;
@ -418,4 +432,3 @@ extern "C" {
#endif #endif
#endif /* __USB_H__ */ #endif /* __USB_H__ */