summaryrefslogtreecommitdiffhomepage
path: root/proto-ft
diff options
context:
space:
mode:
Diffstat (limited to 'proto-ft')
-rw-r--r--proto-ft/ftnoir_ftcontrols.ui209
-rw-r--r--proto-ft/ftnoir_protocol_ft.cpp202
-rw-r--r--proto-ft/ftnoir_protocol_ft.h50
-rw-r--r--proto-ft/ftnoir_protocol_ft_dialog.cpp29
-rw-r--r--proto-ft/lang/nl_NL.ts70
-rw-r--r--proto-ft/lang/ru_RU.ts70
-rw-r--r--proto-ft/lang/stub.ts70
-rw-r--r--proto-ft/lang/zh_CN.ts72
8 files changed, 577 insertions, 195 deletions
diff --git a/proto-ft/ftnoir_ftcontrols.ui b/proto-ft/ftnoir_ftcontrols.ui
index 4ad00514..8edf5a9d 100644
--- a/proto-ft/ftnoir_ftcontrols.ui
+++ b/proto-ft/ftnoir_ftcontrols.ui
@@ -8,17 +8,13 @@
<property name="enabled">
<bool>true</bool>
</property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>571</width>
- <height>0</height>
- </size>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>533</width>
+ <height>326</height>
+ </rect>
</property>
<property name="windowTitle">
<string>freetrack protocol settings</string>
@@ -34,15 +30,15 @@
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="0">
+ <item row="5" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="groupBox_4">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -50,7 +46,7 @@
</sizepolicy>
</property>
<property name="title">
- <string>Repair NPClient location</string>
+ <string>Select interface</string>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignTop</set>
@@ -58,29 +54,33 @@
<property name="flat">
<bool>false</bool>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>9</number>
</property>
<item>
- <widget class="QPushButton" name="bntLocateNPClient">
- <property name="text">
- <string>Locate DLL</string>
- </property>
+ <widget class="QComboBox" name="cbxSelectInterface">
+ <item>
+ <property name="text">
+ <string>Enable both</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Use freetrack, disable TrackIR</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Use TrackIR, disable freetrack</string>
+ </property>
+ </item>
</widget>
</item>
<item>
- <widget class="QLabel" name="label_10">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
+ <widget class="QLabel" name="label_8">
<property name="text">
- <string>Replace the registry entry if you want to use other software with the NPClient protocol and it doesn't work automatically.
-
-Starting tracking will again overwrite the DLL locations.</string>
+ <string>Disable one of the protocols if game is confused by presence of both at the same time.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -90,38 +90,123 @@ Starting tracking will again overwrite the DLL locations.</string>
</layout>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QGroupBox" name="groupBox_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
+ <item row="1" column="0" rowspan="2">
+ <widget class="QGroupBox" name="groupBox_4">
<property name="title">
- <string>Select interface</string>
+ <string>Library location</string>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignTop</set>
</property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <property name="spacing">
- <number>9</number>
- </property>
- <item>
- <widget class="QComboBox" name="cbxSelectInterface"/>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="bntLocateNPClient">
+ <property name="text">
+ <string>Locate DLL</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_10">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Replace the registry entry if you want to use other software with the NPClient protocol and it doesn't work automatically.
+
+Starting tracking will again overwrite the DLL locations.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</item>
- <item>
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>Disable one of the protocols if game is confused by presence of both at the same time.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
+ <item row="1" column="0">
+ <widget class="QWidget" name="widget2" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="enable_custom_location">
+ <property name="toolTip">
+ <string>Useful for titles like Elite: Dangerous that require the library to reside in a specified location. Use this to avoid relocating your opentrack installation.</string>
+ </property>
+ <property name="text">
+ <string>Custom location</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="custom_location">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="set_custom_location">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QWidget" name="widget_2" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="ephemeral_registry_entry">
+ <property name="toolTip">
+ <string>This is useful when you're only evaluating opentrack, and haven't yet decided to use it all the time.</string>
+ </property>
+ <property name="text">
+ <string>Clear location when tracking is stopped</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
</layout>
@@ -129,8 +214,20 @@ Starting tracking will again overwrite the DLL locations.</string>
</item>
</layout>
</widget>
+ <tabstops>
+ <tabstop>cbxSelectInterface</tabstop>
+ <tabstop>bntLocateNPClient</tabstop>
+ <tabstop>enable_custom_location</tabstop>
+ <tabstop>custom_location</tabstop>
+ <tabstop>set_custom_location</tabstop>
+ <tabstop>ephemeral_registry_entry</tabstop>
+ </tabstops>
<resources>
<include location="ft-protocol.qrc"/>
+ <include location="ft-protocol.qrc"/>
+ <include location="ft-protocol.qrc"/>
+ <include location="ft-protocol.qrc"/>
+ <include location="ft-protocol.qrc"/>
</resources>
<connections/>
<slots>
diff --git a/proto-ft/ftnoir_protocol_ft.cpp b/proto-ft/ftnoir_protocol_ft.cpp
index 0c97ffd2..7f710621 100644
--- a/proto-ft/ftnoir_protocol_ft.cpp
+++ b/proto-ft/ftnoir_protocol_ft.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018 Stanislaw Halik <sthalik@misaki.pl>
+/* Copyright (c) 2013-2015, 2017 Stanislaw Halik <sthalik@misaki.pl>
* Copyright (c) 2015 Wim Vriend
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -6,27 +6,39 @@
* copyright notice and this permission notice appear in all copies.
*/
+#include "compat/library-path.hpp"
+
#include "ftnoir_protocol_ft.h"
#include "csv/csv.h"
-#include "compat/library-path.hpp"
+#include <QDir>
-#include <cassert>
#include <cstddef>
-#include <atomic>
#include <cmath>
-#include <cstdlib>
-
#include <windows.h>
-#include <intrin.h>
-static int page_size()
+freetrack::~freetrack()
{
- SYSTEM_INFO system_info;
- GetSystemInfo(&system_info);
- return system_info.dwPageSize;
+ //dummyTrackIR.kill(); dummyTrackIR.waitForFinished();
+ if (s.ephemeral_library_location)
+ {
+ QSettings settings_ft("Freetrack", "FreetrackClient");
+ QSettings settings_npclient("NaturalPoint", "NATURALPOINT\\NPClient Location");
+
+ settings_ft.setValue("Path", "");
+ settings_npclient.setValue("Path", "");
+
+ if (dummyTrackIR.state() == dummyTrackIR.Running)
+ {
+ dummyTrackIR.kill();
+ dummyTrackIR.waitForFinished(100);
+ }
+ }
+ else
+ dummyTrackIR.close();
}
-static_assert(sizeof(LONG) == 4u, "");
+static_assert(sizeof(LONG) == sizeof(std::int32_t));
+static_assert(sizeof(LONG) == 4u);
never_inline void store(float volatile& place, const float value)
{
@@ -34,58 +46,44 @@ never_inline void store(float volatile& place, const float value)
{
float f32;
LONG i32;
- } value_;
+ } value_ {};
value_.f32 = value;
- static_assert(sizeof(value_) == sizeof(float), "");
- static_assert(offsetof(decltype(value_), f32) == offsetof(decltype(value_), i32), "");
+ static_assert(sizeof(value_) == sizeof(float));
+ static_assert(offsetof(decltype(value_), f32) == offsetof(decltype(value_), i32));
(void)InterlockedExchange((LONG volatile*)&place, value_.i32);
}
-template<typename t, typename u>
-force_inline
-std::enable_if_t<(std::is_integral_v<t>) && sizeof(t) == 4>
-store(t volatile& place, u value)
+template<typename t>
+static void store(t volatile& place, t value)
{
- (void)InterlockedExchange((LONG volatile*) &place, value);
+ static_assert(sizeof(t) == 4u);
+ (void)InterlockedExchange((LONG volatile*) &place, (LONG)value);
}
-force_inline std::int32_t load(std::int32_t volatile& place)
+static std::int32_t load(std::int32_t volatile& place)
{
return InterlockedCompareExchange((volatile LONG*) &place, 0, 0);
}
-freetrack::freetrack()
+void freetrack::pose(const double* headpose, const double* raw)
{
-}
+ constexpr double d2r = M_PI/180;
-freetrack::~freetrack()
-{
- if (shm.success())
- {
- store(pMemData->data.DataID, 0);
- store(pMemData->GameID2, -1);
- }
-
- dummyTrackIR.close();
-}
-
-void freetrack::pose(const double* headpose)
-{
- const float yaw = -degrees_to_rads(headpose[Yaw]);
- const float roll = degrees_to_rads(headpose[Roll]);
+ const float yaw = float(-headpose[Yaw] * d2r);
+ const float roll = float(headpose[Roll] * d2r);
const float tx = float(headpose[TX] * 10);
const float ty = float(headpose[TY] * 10);
const float tz = float(headpose[TZ] * 10);
// HACK: Falcon BMS makes a "bump" if pitch is over the value -sh 20170615
- const bool is_crossing_90 = std::fabs(headpose[Pitch] - 90) < 1e-4;
- const float pitch = -degrees_to_rads(is_crossing_90 ? 89.85 : headpose[Pitch]);
+ const bool is_crossing_90 = std::fabs(headpose[Pitch] - 90) < .15;
+ const float pitch = float(-d2r * (is_crossing_90 ? 89.86 : headpose[Pitch]));
- FTHeap* ft = pMemData;
- FTData* data = &ft->data;
+ FTHeap* const ft = pMemData;
+ FTData* const data = &ft->data;
store(data->X, tx);
store(data->Y, ty);
@@ -95,12 +93,14 @@ void freetrack::pose(const double* headpose)
store(data->Pitch, pitch);
store(data->Roll, roll);
- const std::int32_t id = load(ft->GameID);
-
- data_id++;
- data_id %= 128;
+ store(data->RawYaw, float(-raw[Yaw] * d2r));
+ store(data->RawPitch, float(raw[Pitch] * d2r));
+ store(data->RawRoll, float(raw[Roll] * d2r));
+ store(data->RawX, float(raw[TX] * 10));
+ store(data->RawY, float(raw[TY] * 10));
+ store(data->RawZ, float(raw[TZ] * 10));
- store(data->DataID, 60 * 5 + data_id);
+ const std::int32_t id = load(ft->GameID);
if (intGameID != id)
{
@@ -108,45 +108,49 @@ void freetrack::pose(const double* headpose)
union {
unsigned char table[8];
std::int32_t ints[2];
- } t;
+ } t {};
t.ints[0] = 0; t.ints[1] = 0;
(void)CSV::getGameData(id, t.table, gamename);
- static_assert(sizeof(LONG) == 4, "");
- static_assert(sizeof(int) == 4, "");
-
- // memory mappings are page-aligned due to TLB
- if ((std::intptr_t(pMemData) & page_size() - 1) != 0)
- assert(!"proto/freetrack: memory mapping not page aligned");
+ {
+ // FTHeap pMemData happens to be aligned on a page boundary by virtue of
+ // memory mapping usage (MS Windows equivalent of mmap(2)).
+ static_assert((offsetof(FTHeap, table) & (sizeof(LONG)-1)) == 0);
- // no atomic access for `char'
- for (unsigned k = 0; k < 2; k++)
- store(pMemData->table_ints[k], t.ints[k]);
+ for (unsigned k = 0; k < 2; k++)
+ store(pMemData->table_ints[k], t.ints[k]);
+ }
store(ft->GameID2, id);
+ store(data->DataID, 0u);
intGameID = id;
+ if (gamename.isEmpty())
+ gamename = tr("Unknown game");
+
QMutexLocker foo(&game_name_mutex);
connected_game = gamename;
}
+ else
+ (void)InterlockedAdd((LONG volatile*)&data->DataID, 1);
}
-float freetrack::degrees_to_rads(double degrees)
+QString freetrack::game_name()
{
- return float(degrees*M_PI/180);
+ QMutexLocker foo(&game_name_mutex);
+ return connected_game;
}
-void freetrack::start_dummy()
-{
+void freetrack::start_dummy() {
static const QString program = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH "TrackIR.exe";
dummyTrackIR.setProgram("\"" + program + "\"");
dummyTrackIR.start();
}
-void freetrack::set_protocols(bool ft, bool npclient)
+module_status freetrack::set_protocols()
{
static const QString program_dir = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH;
@@ -154,44 +158,61 @@ void freetrack::set_protocols(bool ft, bool npclient)
QSettings settings_ft("Freetrack", "FreetrackClient");
QSettings settings_npclient("NaturalPoint", "NATURALPOINT\\NPClient Location");
- if (ft)
- settings_ft.setValue("Path", program_dir);
- else
- settings_ft.setValue("Path", "");
+ QString location = *s.custom_location_pathname;
+
+ bool use_freetrack = true, use_npclient = true;
+ switch (*s.used_interface)
+ {
+ case settings::enable_npclient: use_freetrack = false; break;
+ case settings::enable_freetrack: use_npclient = false; break;
+ case settings::enable_both: use_freetrack = true; use_npclient = true; break;
+ default:
+ return error(tr("proto/freetrack: wrong interface selection '%1'")
+ .arg(*s.used_interface));
+ }
- if (npclient)
- settings_npclient.setValue("Path", program_dir);
+ if (!s.use_custom_location || s.custom_location_pathname->isEmpty() || !QDir{s.custom_location_pathname}.exists())
+ location = program_dir;
else
- settings_npclient.setValue("Path", "");
+ {
+ bool copy = true;
+
+ if (use_npclient && !QFile{location + "/NPClient.dll"}.exists())
+ copy &= QFile::copy(program_dir + "/NPClient.dll", location + "/NPClient.dll");
+ if (use_npclient && !QFile{location + "/NPClient64.dll"}.exists())
+ copy &= QFile::copy(program_dir + "/NPClient64.dll", location + "/NPClient64.dll");
+ if (use_freetrack && !QFile{location + "/freetrackclient.dll"}.exists())
+ copy &= QFile::copy(program_dir + "/freetrackclient.dll", location + "/freetrackclient.dll");
+ if (use_freetrack && !QFile{location + "/freetrackclient64.dll"}.exists())
+ copy &= QFile::copy(program_dir + "/freetrackclient64.dll", location + "/freetrackclient64.dll");
+
+ if (!copy)
+ return {tr("Can't copy library to selected custom location '%1'").arg(s.custom_location_pathname)};
+ }
+
+ location.replace('\\', '/');
+ if (!location.endsWith('/'))
+ location += '/';
+
+ settings_ft.setValue("Path", use_freetrack ? location : "");
+ settings_npclient.setValue("Path", use_npclient ? location : "");
+
+ return {};
}
module_status freetrack::initialize()
{
if (!shm.success())
- return error(_("Can't load freetrack memory mapping"));
-
- bool use_ft = false, use_npclient = false;
-
- switch (s.intUsedInterface) {
- default:
- case 0:
- use_ft = true;
- use_npclient = true;
- break;
- case 1:
- use_ft = true;
- break;
- case 2:
- use_npclient = true;
- break;
- }
+ return error(tr("Can't load freetrack memory mapping"));
- set_protocols(use_ft, use_npclient);
+ if (auto ret = set_protocols(); !ret.is_ok())
+ return ret;
+ pMemData->data.DataID = 1;
pMemData->data.CamWidth = 100;
pMemData->data.CamHeight = 250;
-#if 1
+#if 0
store(pMemData->data.X1, float(100));
store(pMemData->data.Y1, float(200));
store(pMemData->data.X2, float(300));
@@ -200,14 +221,13 @@ module_status freetrack::initialize()
store(pMemData->data.Y3, float(100));
#endif
- store(pMemData->GameID2, -1);
- store(pMemData->data.DataID, 0);
+ store(pMemData->GameID2, 0);
for (unsigned k = 0; k < 2; k++)
store(pMemData->table_ints[k], 0);
// more games need the dummy executable than previously thought
- if (use_npclient)
+ if (s.used_interface != settings::enable_freetrack)
start_dummy();
return status_ok();
diff --git a/proto-ft/ftnoir_protocol_ft.h b/proto-ft/ftnoir_protocol_ft.h
index 843d1f34..a07747d9 100644
--- a/proto-ft/ftnoir_protocol_ft.h
+++ b/proto-ft/ftnoir_protocol_ft.h
@@ -7,60 +7,61 @@
*/
#pragma once
-
#include "ui_ftnoir_ftcontrols.h"
-
-#include "freetrackclient/fttypes.h"
-
-#include "compat/shm.h"
-#include "options/options.hpp"
#include "api/plugin-api.hpp"
#include <QProcess>
#include <QString>
#include <QMutex>
+#include <QDebug>
+
#include <cinttypes>
+#include "freetrackclient/fttypes.h"
+
+#include "compat/shm.h"
+#include "options/options.hpp"
+
#include <memory>
using namespace options;
struct settings : opts {
- value<int> intUsedInterface;
- settings() :
- opts("proto-freetrack"),
- intUsedInterface(b, "used-interfaces", 0)
- {}
+ enum enable_status : int { enable_both, enable_freetrack, enable_npclient, };
+ value<int> used_interface{b, "used-interfaces", (int)enable_both};
+ value<bool> ephemeral_library_location{b, "ephemeral-library-location", false};
+ value<bool> use_custom_location{b, "use-custom-location", false};
+ value<QString> custom_location_pathname{b, "custom-library-location", {}};
+ settings() : opts("proto-freetrack") {}
};
-class freetrack : public IProtocol
+class freetrack : TR, public IProtocol
{
+ Q_OBJECT
+
public:
- freetrack();
+ freetrack() = default;
~freetrack() override;
module_status initialize() override;
- void pose( const double *headpose );
- QString game_name() override {
- QMutexLocker foo(&game_name_mutex);
- return connected_game;
- }
+ void pose(const double* pose, const double*) override;
+ QString game_name() override;
private:
settings s;
shm_wrapper shm { FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap) };
- FTHeap *pMemData { (FTHeap*) shm.ptr() };
+ FTHeap* pMemData { (FTHeap*) shm.ptr() };
QProcess dummyTrackIR;
int intGameID = -1;
QString connected_game;
QMutex game_name_mutex;
- unsigned data_id = 0;
void start_dummy();
- static float degrees_to_rads(double degrees);
public:
- static void set_protocols(bool ft, bool npclient);
+ enum class status { starting, stopping };
+ [[nodiscard]] module_status set_protocols();
+ void clear_protocols();
};
class FTControls: public IProtocolDialog
@@ -77,11 +78,14 @@ private slots:
void selectDLL();
void doOK();
void doCancel();
+ void set_custom_location();
};
class freetrackDll : public Metadata
{
+ Q_OBJECT
+
public:
- QString name() { return otr_tr("freetrack 2.0 Enhanced"); }
+ QString name() { return tr("freetrack 2.0 Enhanced"); }
QIcon icon() { return QIcon(":/images/freetrack.png"); }
};
diff --git a/proto-ft/ftnoir_protocol_ft_dialog.cpp b/proto-ft/ftnoir_protocol_ft_dialog.cpp
index df2878ec..90ff059a 100644
--- a/proto-ft/ftnoir_protocol_ft_dialog.cpp
+++ b/proto-ft/ftnoir_protocol_ft_dialog.cpp
@@ -8,11 +8,11 @@
* purpose with or without fee is hereby granted, provided that the above *
* copyright notice and this permission notice appear in all copies. *
*/
-#include "ftnoir_protocol_ft.h"
-#include "compat/library-path.hpp"
+#include "compat/library-path.hpp"
+#include "ftnoir_protocol_ft.h"
+#include <QDebug>
#include <QFileDialog>
-#include <QFileInfo>
FTControls::FTControls()
{
@@ -22,11 +22,12 @@ FTControls::FTControls()
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
connect(ui.bntLocateNPClient, SIGNAL(clicked()), this, SLOT(selectDLL()));
- ui.cbxSelectInterface->addItem("Enable both");
- ui.cbxSelectInterface->addItem("Use FreeTrack, hide TrackIR");
- ui.cbxSelectInterface->addItem("Use TrackIR, hide FreeTrack");
+ tie_setting(s.used_interface, ui.cbxSelectInterface);
+ tie_setting(s.ephemeral_library_location, ui.ephemeral_registry_entry);
+ tie_setting(s.custom_location_pathname, ui.custom_location);
+ tie_setting(s.use_custom_location, ui.enable_custom_location);
- tie_setting(s.intUsedInterface, ui.cbxSelectInterface);
+ connect(ui.set_custom_location, &QAbstractButton::clicked, this, &FTControls::set_custom_location);
}
void FTControls::doOK()
@@ -54,4 +55,16 @@ void FTControls::selectDLL()
node.setValue("Path", dllname.dir().path());
}
}
-
+void FTControls::set_custom_location()
+{
+ static const auto program_directory = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH;
+ auto previous_location = *s.custom_location_pathname;
+ if (!s.use_custom_location || previous_location.isEmpty() || !QDir{previous_location}.exists())
+ previous_location = program_directory;
+ auto dir = QFileDialog::getExistingDirectory(this, tr("Select library location"), previous_location);
+ if (dir.isEmpty() || !QDir{dir}.exists())
+ dir = QString{};
+ else
+ ui.enable_custom_location->setEnabled(true);
+ ui.custom_location->setText(dir);
+}
diff --git a/proto-ft/lang/nl_NL.ts b/proto-ft/lang/nl_NL.ts
index 5f68fb99..c8603973 100644
--- a/proto-ft/lang/nl_NL.ts
+++ b/proto-ft/lang/nl_NL.ts
@@ -11,6 +11,10 @@
<source>Dll file (*.dll);;All Files (*)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select library location</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UICFTControls</name>
@@ -27,10 +31,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Repair NPClient location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Locate DLL</source>
<translation type="unfinished"></translation>
</message>
@@ -40,5 +40,67 @@
Starting tracking will again overwrite the DLL locations.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Enable both</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use freetrack, disable TrackIR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use TrackIR, disable freetrack</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Library location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Browse...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is useful when you&apos;re only evaluating opentrack, and haven&apos;t yet decided to use it all the time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear location when tracking is stopped</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Useful for titles like Elite: Dangerous that require the library to reside in a specified location. Use this to avoid relocating your opentrack installation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrack</name>
+ <message>
+ <source>Unknown game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t load freetrack memory mapping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t copy library to selected custom location &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>proto/freetrack: wrong interface selection &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrackDll</name>
+ <message>
+ <source>freetrack 2.0 Enhanced</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
</TS>
diff --git a/proto-ft/lang/ru_RU.ts b/proto-ft/lang/ru_RU.ts
index 31d0a2be..a6433fd5 100644
--- a/proto-ft/lang/ru_RU.ts
+++ b/proto-ft/lang/ru_RU.ts
@@ -11,6 +11,10 @@
<source>Dll file (*.dll);;All Files (*)</source>
<translation></translation>
</message>
+ <message>
+ <source>Select library location</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UICFTControls</name>
@@ -27,10 +31,6 @@
<translation>Отключите один из протоколов в случае, если при включении обоих интерфейсов игра не корректно определяет их.</translation>
</message>
<message>
- <source>Repair NPClient location</source>
- <translation>Решение проблем с расположением NPClient&apos;а </translation>
- </message>
- <message>
<source>Locate DLL</source>
<translation>Укажите DLL</translation>
</message>
@@ -42,5 +42,67 @@ Starting tracking will again overwrite the DLL locations.</source>
Запуск отслеживания в opentrack приведет к перезаписи расположения DLL-файла.</translation>
</message>
+ <message>
+ <source>Enable both</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use freetrack, disable TrackIR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use TrackIR, disable freetrack</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Library location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Browse...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is useful when you&apos;re only evaluating opentrack, and haven&apos;t yet decided to use it all the time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear location when tracking is stopped</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Useful for titles like Elite: Dangerous that require the library to reside in a specified location. Use this to avoid relocating your opentrack installation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrack</name>
+ <message>
+ <source>Unknown game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t load freetrack memory mapping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t copy library to selected custom location &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>proto/freetrack: wrong interface selection &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrackDll</name>
+ <message>
+ <source>freetrack 2.0 Enhanced</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
</TS>
diff --git a/proto-ft/lang/stub.ts b/proto-ft/lang/stub.ts
index 4fb52c8c..ac88d895 100644
--- a/proto-ft/lang/stub.ts
+++ b/proto-ft/lang/stub.ts
@@ -11,6 +11,10 @@
<source>Dll file (*.dll);;All Files (*)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select library location</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UICFTControls</name>
@@ -27,10 +31,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Repair NPClient location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Locate DLL</source>
<translation type="unfinished"></translation>
</message>
@@ -40,5 +40,67 @@
Starting tracking will again overwrite the DLL locations.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Enable both</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use freetrack, disable TrackIR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use TrackIR, disable freetrack</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Library location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Browse...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is useful when you&apos;re only evaluating opentrack, and haven&apos;t yet decided to use it all the time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear location when tracking is stopped</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Useful for titles like Elite: Dangerous that require the library to reside in a specified location. Use this to avoid relocating your opentrack installation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrack</name>
+ <message>
+ <source>Unknown game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t load freetrack memory mapping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t copy library to selected custom location &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>proto/freetrack: wrong interface selection &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrackDll</name>
+ <message>
+ <source>freetrack 2.0 Enhanced</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
</TS>
diff --git a/proto-ft/lang/zh_CN.ts b/proto-ft/lang/zh_CN.ts
index 63791bc8..7706d27c 100644
--- a/proto-ft/lang/zh_CN.ts
+++ b/proto-ft/lang/zh_CN.ts
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
-<TS version="2.1">
+<TS version="2.1" language="zh_CN">
<context>
<name>FTControls</name>
<message>
@@ -11,6 +11,10 @@
<source>Dll file (*.dll);;All Files (*)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select library location</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UICFTControls</name>
@@ -19,10 +23,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Repair NPClient location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Locate DLL</source>
<translation type="unfinished"></translation>
</message>
@@ -40,5 +40,67 @@ Starting tracking will again overwrite the DLL locations.</source>
<source>Disable one of the protocols if game is confused by presence of both at the same time.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Enable both</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use freetrack, disable TrackIR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use TrackIR, disable freetrack</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Library location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Browse...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is useful when you&apos;re only evaluating opentrack, and haven&apos;t yet decided to use it all the time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear location when tracking is stopped</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Useful for titles like Elite: Dangerous that require the library to reside in a specified location. Use this to avoid relocating your opentrack installation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrack</name>
+ <message>
+ <source>Unknown game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t load freetrack memory mapping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Can&apos;t copy library to selected custom location &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>proto/freetrack: wrong interface selection &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>freetrackDll</name>
+ <message>
+ <source>freetrack 2.0 Enhanced</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
</TS>