From 8aae10467b307569e8dc34cc42306ab5335274dd Mon Sep 17 00:00:00 2001 From: Alessandro Menezes Date: Tue, 17 Jan 2017 23:51:15 -0300 Subject: [PATCH] Fix: making it compatible with xbox 360 controller emulator --- GenericFFBDriver/FFBDriver.cpp | 18 +++- .../vibration/VibrationController.cpp | 96 ++++++++++++++----- 2 files changed, 89 insertions(+), 25 deletions(-) diff --git a/GenericFFBDriver/FFBDriver.cpp b/GenericFFBDriver/FFBDriver.cpp index c9888e2..81fd6fd 100644 --- a/GenericFFBDriver/FFBDriver.cpp +++ b/GenericFFBDriver/FFBDriver.cpp @@ -4,7 +4,7 @@ #include void LogMessage(const char* msg) { - +#ifdef _DEBUG SYSTEMTIME st; GetSystemTime(&st); char buffer[256]; @@ -20,6 +20,7 @@ void LogMessage(const char* msg) { outfile.open("J:\\Gamepad\\driverlog.txt", std::ios_base::app); outfile << buffer; outfile.close(); +#endif } FFBDriver::FFBDriver() @@ -28,6 +29,7 @@ FFBDriver::FFBDriver() FFBDriver::~FFBDriver() { + vibration::VibrationController::Reset(); } @@ -66,7 +68,9 @@ HRESULT STDMETHODCALLTYPE FFBDriver::DeviceID( } HRESULT STDMETHODCALLTYPE FFBDriver::GetVersions(LPDIDRIVERVERSIONS lpVersions) { +#ifdef _DEBUG LogMessage("GetVersions\n"); +#endif lpVersions->dwFFDriverVersion = 0x100; lpVersions->dwFirmwareRevision = 0x100; @@ -75,7 +79,9 @@ HRESULT STDMETHODCALLTYPE FFBDriver::GetVersions(LPDIDRIVERVERSIONS lpVersions) return S_OK; } HRESULT STDMETHODCALLTYPE FFBDriver::Escape(THIS_ DWORD, DWORD, LPDIEFFESCAPE) { +#ifdef _DEBUG LogMessage("Escape!\n"); +#endif return S_OK; } HRESULT STDMETHODCALLTYPE FFBDriver::SetGain( @@ -131,7 +137,9 @@ HRESULT STDMETHODCALLTYPE FFBDriver::SendForceFeedbackCommand( } HRESULT STDMETHODCALLTYPE FFBDriver::GetForceFeedbackState(THIS_ DWORD, LPDIDEVICESTATE) { +#ifdef _DEBUG LogMessage("GetForceFeedbackState!\n"); +#endif return S_OK; } @@ -155,18 +163,26 @@ HRESULT STDMETHODCALLTYPE FFBDriver::DownloadEffect( } HRESULT STDMETHODCALLTYPE FFBDriver::DestroyEffect(DWORD, DWORD) { +#ifdef _DEBUG LogMessage("DestroyEffect!\n"); +#endif return S_OK; } HRESULT STDMETHODCALLTYPE FFBDriver::StartEffect(DWORD, DWORD, DWORD, DWORD) { +#ifdef _DEBUG LogMessage("StartEffect!\n"); +#endif return S_OK; } HRESULT STDMETHODCALLTYPE FFBDriver::StopEffect(DWORD dwID, DWORD dwEffect) { +#ifdef _DEBUG LogMessage("StopEffect!\n"); +#endif return S_OK; } HRESULT STDMETHODCALLTYPE FFBDriver::GetEffectStatus(DWORD, DWORD, LPDWORD) { +#ifdef _DEBUG LogMessage("GetEffectStatus!\n"); +#endif return S_OK; } diff --git a/GenericFFBDriver/vibration/VibrationController.cpp b/GenericFFBDriver/vibration/VibrationController.cpp index 73a8b89..13a9f6d 100644 --- a/GenericFFBDriver/vibration/VibrationController.cpp +++ b/GenericFFBDriver/vibration/VibrationController.cpp @@ -63,8 +63,10 @@ namespace vibration { if (thrVibration == NULL) { quitVibrationThread = false; - for (int k = 0; k < MAX_EFFECTS; k++) + for (int k = 0; k < MAX_EFFECTS; k++) { VibEffects[k].isActive = FALSE; + VibEffects[k].dwEffectId = -1; + } thrVibration.reset(new std::thread(VibrationController::VibrationThreadEntryPoint)); } @@ -171,47 +173,93 @@ namespace vibration { void VibrationController::StartEffect(DWORD dwEffectID, LPCDIEFFECT peff) { mtxSync.lock(); + + int idx = -1; + // Reusing the same idx if effect was already created for (int k = 0; k < MAX_EFFECTS; k++) { - if (VibEffects[k].isActive && k < MAX_EFFECTS - 1) - continue; + if (VibEffects[k].dwEffectId == dwEffectID) { + idx = k; + break; + } + } - // Calculating intensity - byte forceX = 0xfe; - byte forceY = 0xfe; + // Find a non-active idx + if (idx < 0) { + for (int k = 0; k < MAX_EFFECTS; k++) { + if (!VibEffects[k].isActive || k == MAX_EFFECTS - 1) { + idx = k; + break; + } + } + } + + // Calculating intensity + byte forceX = 0xfe; + byte forceY = 0xfe; + + byte magnitude = 0xfe; + if (peff->cbTypeSpecificParams == 4) { + LPDICONSTANTFORCE effParams = (LPDICONSTANTFORCE)peff->lpvTypeSpecificParams; + magnitude = (byte)(round((((double)effParams->lMagnitude) / 10000.0) * 254.0)); + } + if (peff->cAxes == 1) { + // If direction is negative, then it is a forceX + // Otherwise it is a forceY + LONG direction = peff->rglDirection[0]; + static byte lastForceX = 0; + static byte lastForceY = 0; + + forceX = lastForceX; + forceY = lastForceY; + + if (direction == -1) { + //forceX = lastForceX = (byte)(round((((double)peff->dwGain) / 10000.0) * 254.0)); + forceX = lastForceX = magnitude; + } + else if (direction == 1) { + //forceY = lastForceY = (byte)(round((((double)peff->dwGain) / 10000.0) * 254.0)); + forceY = lastForceY = magnitude; + } + + } + else { if (peff->cAxes >= 1) { LONG fx = peff->rglDirection[0]; - if (fx <= 1) fx = peff->dwGain; + //if (fx <= 1) fx = peff->dwGain; - forceX = forceY = (byte)abs(round((((double)fx) / 10000.0) * 254.0)); + if (fx > 0) + forceX = forceY = magnitude; + else + forceX = forceY = 0; } if (peff->cAxes >= 2) { LONG fy = peff->rglDirection[1]; - if (fy <= 1) fy = peff->dwGain; + //if (fy <= 1) fy = peff->dwGain; - forceY = (byte)abs(round((((double)fy) / 10000.0) * 254.0)); + if (fy > 0) + forceY = magnitude; + else + forceY = 0; } + } - DWORD frame = GetTickCount(); - - VibEffects[k].forceX = forceX; - VibEffects[k].forceY = forceY; + DWORD frame = GetTickCount(); - VibEffects[k].dwEffectId = dwEffectID; - VibEffects[k].dwStartFrame = frame + (peff->dwStartDelay / 1000); - VibEffects[k].dwStopFrame = - peff->dwDuration == INFINITE ? INFINITE : - VibEffects[k].dwStartFrame + (peff->dwDuration / 1000); - VibEffects[k].isActive = TRUE; - VibEffects[k].started = FALSE; + VibEffects[idx].forceX = forceX; + VibEffects[idx].forceY = forceY; - break; - } + VibEffects[idx].dwEffectId = dwEffectID; + VibEffects[idx].dwStartFrame = frame + (peff->dwStartDelay / 1000); + VibEffects[idx].dwStopFrame = + peff->dwDuration == INFINITE ? INFINITE : + VibEffects[idx].dwStartFrame + (peff->dwDuration / 1000); + VibEffects[idx].isActive = TRUE; + VibEffects[idx].started = FALSE; mtxSync.unlock(); - StartVibrationThread(); }