Skip to content

Commit

Permalink
Fix: making it compatible with xbox 360 controller emulator
Browse files Browse the repository at this point in the history
  • Loading branch information
alessandroasm committed Jan 18, 2017
1 parent fc342be commit 8aae104
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 25 deletions.
18 changes: 17 additions & 1 deletion GenericFFBDriver/FFBDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <fstream>

void LogMessage(const char* msg) {

#ifdef _DEBUG
SYSTEMTIME st;
GetSystemTime(&st);
char buffer[256];
Expand All @@ -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()
Expand All @@ -28,6 +29,7 @@ FFBDriver::FFBDriver()

FFBDriver::~FFBDriver()
{
vibration::VibrationController::Reset();
}


Expand Down Expand Up @@ -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;
Expand All @@ -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(
Expand Down Expand Up @@ -131,7 +137,9 @@ HRESULT STDMETHODCALLTYPE FFBDriver::SendForceFeedbackCommand(
}

HRESULT STDMETHODCALLTYPE FFBDriver::GetForceFeedbackState(THIS_ DWORD, LPDIDEVICESTATE) {
#ifdef _DEBUG
LogMessage("GetForceFeedbackState!\n");
#endif
return S_OK;
}

Expand All @@ -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;
}
96 changes: 72 additions & 24 deletions GenericFFBDriver/vibration/VibrationController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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();
}

Expand Down

0 comments on commit 8aae104

Please sign in to comment.