Skip to content

Commit

Permalink
Save/restore settings to/from the registry
Browse files Browse the repository at this point in the history
Cosine replaces linear interpolation for 60 Hz interpolated types
  • Loading branch information
nlp80 committed Dec 16, 2016
1 parent c5d1cd8 commit 2b1bef7
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 22 deletions.
112 changes: 91 additions & 21 deletions irFFB/irFFB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DI_MAX 10000
#define MINFORCE_MULTIPLIER 20
#define STOPS_MAXFORCE_RAD 0.175f // 10 deg
#define KEY_PATH L"Software\\irFFB\\Settings"

enum ffbType {
FFBTYPE_60HZ,
Expand Down Expand Up @@ -93,7 +94,7 @@ WCHAR szWindowClass[MAX_LOADSTRING];
LPDIRECTINPUT8 pDI = nullptr;
GUID ffdevices[MAX_FFB_DEVICES];
int ffdeviceIdx = 0;
GUID *devGuid = nullptr;
GUID devGuid = GUID_NULL;
LPDIRECTINPUTDEVICE8 ffdevice = nullptr;
LPDIRECTINPUTEFFECT effect = nullptr;

Expand All @@ -103,6 +104,8 @@ LONG dir[1] = { 0 };
DIPERIODIC pforce;
DIEFFECT dieff;

float cosInterp[6];

int ffb, origFFB, testFFB;
int force = 0, minForce = 0, maxForce = 0, delayTicks = 0;

Expand Down Expand Up @@ -221,11 +224,9 @@ DWORD WINAPI directFFBThread(LPVOID lParam) {

QueryPerformanceCounter(&start);

int diffPerSample = (force - lastSample) / DIRECT_INTERP_SAMPLES;

for (int i = 1; i < DIRECT_INTERP_SAMPLES; i++) {

setFFB(lastSample + diffPerSample * i);
setFFB(f2i((float)lastSample * (1 - cosInterp[i]) + (float)force * cosInterp[i]));
sleepSpinUntil(&start, 2000, 2760 * i);

}
Expand Down Expand Up @@ -274,8 +275,12 @@ int APIENTRY wWinMain(
LoadStringW(hInstance, IDC_IRFFB, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

if (!InitInstance(hInstance, nCmdShow))
return FALSE;
cosInterp[0] = 0;
for (int i = 1; i < 6; i++) {
cosInterp[i] = (1.0f - cosf((float)M_PI * (float)i / 6)) / 2;
}

readSettings();

// Setup DI FFB effect
pforce.dwMagnitude = 0;
Expand All @@ -299,6 +304,9 @@ int APIENTRY wWinMain(
dieff.lpvTypeSpecificParams = &pforce;
dieff.dwStartDelay = 0;

if (!InitInstance(hInstance, nCmdShow))
return FALSE;

LARGE_INTEGER start;
QueryPerformanceFrequency(&freq);

Expand Down Expand Up @@ -509,11 +517,9 @@ int APIENTRY wWinMain(

QueryPerformanceCounter(&start);

float diffPerSample = (*swTorque - lastTorque) / swTSTnumSamples;

for (int i = 1; i < swTSTnumSamples; i++) {

setFFB(scaleTorque(lastTorque + diffPerSample * i));
setFFB(scaleTorque(lastTorque * (1 - cosInterp[i]) + *swTorque * cosInterp[i]));
sleepSpinUntil(&start, 2000, 2760 * i);

}
Expand Down Expand Up @@ -739,21 +745,20 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {
SendMessage(cmpWnd, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(ffbTypeString(i)));
}

SendMessage(ffbWnd, CB_SETCURSEL, FFBTYPE_60HZ, 0);
ffb = origFFB = FFBTYPE_60HZ;
SendMessage(ffbWnd, CB_SETCURSEL, ffb, 0);
origFFB = ffb;

SendMessage(cmpWnd, CB_SETCURSEL, FFBTYPE_360HZ, 0);
testFFB = FFBTYPE_360HZ;
SendMessage(cmpWnd, CB_SETCURSEL, testFFB, 0);

slider(&minWnd, L"Min force:", 216, L"0", L"20");
SendMessage(minWnd, TBM_SETRANGE, TRUE, MAKELPARAM(0, 20));
minForce = 0;
SendMessage(minWnd, TBM_SETPOS, TRUE, minForce);
SendMessage(minWnd, TBM_SETPOSNOTIFY, 0, minForce);

slider(&maxWnd, L"Max force:", 288, L"5 Nm", L"65 Nm");
SendMessage(maxWnd, TBM_SETRANGE, TRUE, MAKELPARAM(5, 65));
SendMessage(maxWnd, TBM_SETPOS, TRUE, 45);
SendMessage(maxWnd, TBM_SETPOSNOTIFY, 0, 45);
maxForce = 45;
SendMessage(maxWnd, TBM_SETPOS, TRUE, maxForce);
SendMessage(maxWnd, TBM_SETPOSNOTIFY, 0, maxForce);

slider(&delayWnd, L"Extra latency:", 360, L"0 ticks", L"20 ticks");
SendMessage(delayWnd, TBM_SETRANGE, TRUE, MAKELPARAM(0, 20));
Expand Down Expand Up @@ -805,7 +810,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

int idx = (int)SendMessage(devWnd, CB_GETCURSEL, 0, 0);
if (idx < ffdeviceIdx) {
devGuid = &ffdevices[idx];
devGuid = ffdevices[idx];
initDirectInput();
}

Expand Down Expand Up @@ -884,6 +889,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

case WM_DESTROY: {
releaseAll();
writeSettings();
exit(0);
}
break;
Expand Down Expand Up @@ -938,9 +944,16 @@ BOOL CALLBACK EnumFFDevicesCallback(LPCDIDEVICEINSTANCE diDevInst, VOID *wnd) {
if (ffdeviceIdx == MAX_FFB_DEVICES)
return false;

ffdevices[ffdeviceIdx++] = diDevInst->guidInstance;
ffdevices[ffdeviceIdx] = diDevInst->guidInstance;
SendMessage((HWND)wnd, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(diDevInst->tszProductName));

if (devGuid == diDevInst->guidInstance) {
SendMessage((HWND)wnd, CB_SETCURSEL, ffdeviceIdx, 0);
initDirectInput();
}

ffdeviceIdx++;

return true;

}
Expand Down Expand Up @@ -1007,7 +1020,7 @@ void initDirectInput() {
return;
}

if (FAILED(pDI->CreateDevice(*devGuid, &ffdevice, nullptr))) {
if (FAILED(pDI->CreateDevice(devGuid, &ffdevice, nullptr))) {
text(L"Failed to create DI device");
return;
}
Expand Down Expand Up @@ -1049,7 +1062,7 @@ void initDirectInput() {
}

if (FAILED(ffdevice->CreateEffect(GUID_Sine, &dieff, &effect, nullptr))) {
text(L"Failed to create Sine periodic effect");
text(L"Failed to create sine periodic effect");
return;
}

Expand Down Expand Up @@ -1200,6 +1213,63 @@ bool initVJD() {

}

void readSettings() {

wchar_t dguid[GUIDSTRING_MAX];
HKEY regKey;
DWORD sz = sizeof(int);
DWORD dgsz = sizeof(dguid);

if (!RegOpenKeyEx(HKEY_CURRENT_USER, KEY_PATH, 0, KEY_ALL_ACCESS, &regKey)) {

if (!RegGetValue(regKey, nullptr, L"device", RRF_RT_REG_SZ, nullptr, dguid, &dgsz))
if (FAILED(IIDFromString(dguid, &devGuid)))
devGuid = GUID_NULL;
if (RegGetValue(regKey, nullptr, L"ffb", RRF_RT_REG_DWORD, nullptr, &ffb, &sz))
ffb = FFBTYPE_60HZ;
if (RegGetValue(regKey, nullptr, L"testFFB", RRF_RT_REG_DWORD, nullptr, &testFFB, &sz))
testFFB = FFBTYPE_360HZ;
if (RegGetValue(regKey, nullptr, L"maxForce", RRF_RT_REG_DWORD, nullptr, &maxForce, &sz))
maxForce = 45;
if (RegGetValue(regKey, nullptr, L"minForce", RRF_RT_REG_DWORD, nullptr, &minForce, &sz))
minForce = 0;

}
else {
ffb = FFBTYPE_60HZ;
testFFB = FFBTYPE_360HZ;
minForce = 0;
maxForce = 45;
}

}

void writeSettings() {

wchar_t *guid;
HKEY regKey;
DWORD sz = sizeof(int);

RegCreateKeyEx(
HKEY_CURRENT_USER, KEY_PATH, 0, nullptr,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr, &regKey, nullptr
);

if (!RegOpenKeyEx(HKEY_CURRENT_USER, KEY_PATH, 0, KEY_ALL_ACCESS, &regKey)) {

if (SUCCEEDED(StringFromCLSID(devGuid, (LPOLESTR *)&guid))) {
int len = (lstrlenW(guid) + 1) * sizeof(wchar_t);
RegSetValueEx(regKey, L"device", 0, REG_SZ, (BYTE *)guid, len);
}
RegSetValueEx(regKey, L"ffb", 0, REG_DWORD, (BYTE *)&ffb, sz);
RegSetValueEx(regKey, L"testFFB", 0, REG_DWORD, (BYTE *)&testFFB, sz);
RegSetValueEx(regKey, L"maxForce", 0, REG_DWORD, (BYTE *)&maxForce, sz);
RegSetValueEx(regKey, L"minForce", 0, REG_DWORD, (BYTE *)&minForce, sz);

}

}

void initAll() {

initVJD();
Expand Down
2 changes: 2 additions & 0 deletions irFFB/irFFB.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ inline int f2i(float);
inline void sleepSpinUntil(PLARGE_INTEGER, UINT, UINT);
inline int scaleTorque(float);
inline void setFFB(int);
void readSettings();
void writeSettings();
void initAll();
void releaseAll();

Expand Down
3 changes: 2 additions & 1 deletion irFFB/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <cmath>

#include <Strsafe.h>
#include <Shlobj.h>

#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

#define _USE_MATH_DEFINES
#include <cmath>
#include <chrono>
#include <thread>

Expand Down

0 comments on commit 2b1bef7

Please sign in to comment.