summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]proto-ft/ftnoir_protocol_ft.cpp42
-rwxr-xr-x[-rw-r--r--]proto-ft/ftnoir_protocol_ft.h16
-rwxr-xr-xproto-ft/mutex.cpp64
3 files changed, 107 insertions, 15 deletions
diff --git a/proto-ft/ftnoir_protocol_ft.cpp b/proto-ft/ftnoir_protocol_ft.cpp
index 05253174..134ffc53 100644..100755
--- a/proto-ft/ftnoir_protocol_ft.cpp
+++ b/proto-ft/ftnoir_protocol_ft.cpp
@@ -16,6 +16,7 @@ FTNoIR_Protocol::FTNoIR_Protocol() :
viewsStop(nullptr),
intGameID(0)
{
+ runonce_check->try_runonce();
}
FTNoIR_Protocol::~FTNoIR_Protocol()
@@ -27,6 +28,7 @@ FTNoIR_Protocol::~FTNoIR_Protocol()
dummyTrackIR.terminate();
dummyTrackIR.kill();
dummyTrackIR.waitForFinished(50);
+ runonce_check->try_exit();
}
void FTNoIR_Protocol::pose(const double* headpose) {
@@ -108,44 +110,54 @@ void FTNoIR_Protocol::start_tirviews() {
}
void FTNoIR_Protocol::start_dummy() {
-
-
QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe";
dummyTrackIR.setProgram("\"" + program + "\"");
dummyTrackIR.start();
}
-bool FTNoIR_Protocol::correct()
+void FTNoIR_Protocol::set_protocols(bool ft, bool npclient)
{
+ const QString program_dir = QCoreApplication::applicationDirPath() + "/";
+
// Registry settings (in HK_USER)
- QSettings settings("Freetrack", "FreetrackClient");
- QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location");
+ 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", "");
+
+ if (npclient)
+ settings_npclient.setValue("Path", program_dir);
+ else
+ settings_npclient.setValue("Path", "");
+}
+bool FTNoIR_Protocol::correct()
+{
if (!shm.success())
return false;
- QString aLocation = QCoreApplication::applicationDirPath() + "/";
+ bool use_ft = false, use_npclient = false;
switch (s.intUsedInterface) {
case 0:
- // Use both interfaces
- settings.setValue( "Path" , aLocation );
- settingsTIR.setValue( "Path" , aLocation );
+ use_ft = true;
+ use_npclient = true;
break;
case 1:
- // Use FreeTrack, disable TrackIR
- settings.setValue( "Path" , aLocation );
- settingsTIR.setValue( "Path" , "" );
+ use_ft = true;
break;
case 2:
- // Use TrackIR, disable FreeTrack
- settings.setValue( "Path" , "" );
- settingsTIR.setValue( "Path" , aLocation );
+ use_npclient = true;
break;
default:
break;
}
+ set_protocols(use_ft, use_npclient);
+
if (s.useTIRViews) {
start_tirviews();
}
diff --git a/proto-ft/ftnoir_protocol_ft.h b/proto-ft/ftnoir_protocol_ft.h
index 9cf16f03..8940e5d8 100644..100755
--- a/proto-ft/ftnoir_protocol_ft.h
+++ b/proto-ft/ftnoir_protocol_ft.h
@@ -21,6 +21,8 @@
#include "opentrack-compat/shm.h"
#include "opentrack-compat/options.hpp"
#include "freetrackclient/fttypes.h"
+#include <memory>
+
using namespace options;
struct settings : opts {
@@ -36,6 +38,15 @@ struct settings : opts {
typedef void (__stdcall *importTIRViewsStart)(void);
typedef void (__stdcall *importTIRViewsStop)(void);
+// for runonce, see mutex.cpp
+struct runonce
+{
+ virtual void try_runonce() = 0;
+ virtual void try_exit() = 0;
+ virtual bool is_first_run() = 0;
+ virtual ~runonce() {}
+};
+
class FTNoIR_Protocol : public IProtocol
{
public:
@@ -61,9 +72,14 @@ private:
QString connected_game;
QMutex game_name_mutex;
+ static std::unique_ptr<runonce> runonce_check;
+
static inline double getRadsFromDegrees(double degrees) { return degrees * 0.017453; }
void start_tirviews();
void start_dummy();
+
+public:
+ static void set_protocols(bool ft, bool npclient);
};
class FTControls: public IProtocolDialog
diff --git a/proto-ft/mutex.cpp b/proto-ft/mutex.cpp
new file mode 100755
index 00000000..0d50c9bd
--- /dev/null
+++ b/proto-ft/mutex.cpp
@@ -0,0 +1,64 @@
+#include "ftnoir_protocol_ft.h"
+#include <windows.h>
+
+class check_for_first_run : public runonce
+{
+ bool checked_for_first_run;
+ bool is_first_instance;
+
+public:
+ bool is_first_run() override
+ {
+ return checked_for_first_run && is_first_instance;
+ }
+
+ void try_runonce() override
+ {
+ constexpr const char* name = "opentrack-freetrack-runonce";
+
+ if (checked_for_first_run)
+ return;
+
+ // just leak it, no issue
+ HANDLE h = CreateMutexA(nullptr, false, name);
+
+ switch (WaitForSingleObject(h, 0))
+ {
+ case WAIT_OBJECT_0:
+ is_first_instance = true;
+ checked_for_first_run = true;
+ break;
+ case WAIT_TIMEOUT:
+ checked_for_first_run = true;
+ break;
+ default:
+ checked_for_first_run = false;
+ break;
+ }
+
+ if (checked_for_first_run && !is_first_instance)
+ CloseHandle(h);
+
+ qDebug() << "ft runonce:" << "first-run" << is_first_instance << "checked" << checked_for_first_run;
+ }
+
+ void try_exit() override
+ {
+ if (is_first_instance)
+ {
+ qDebug() << "ft runonce: removing registry keys";
+ FTNoIR_Protocol::set_protocols(false, false);
+ }
+ }
+
+public:
+ check_for_first_run() : checked_for_first_run(false), is_first_instance(false)
+ {
+ }
+ ~check_for_first_run()
+ {
+ try_exit();
+ }
+};
+
+std::unique_ptr<runonce> FTNoIR_Protocol::runonce_check = std::unique_ptr<runonce>(static_cast<runonce*>(new check_for_first_run()));