summaryrefslogtreecommitdiffhomepage
path: root/protocol-wine
diff options
context:
space:
mode:
Diffstat (limited to 'protocol-wine')
-rw-r--r--protocol-wine/CMakeLists.txt26
-rw-r--r--protocol-wine/ftnoir_protocol_wine.cpp59
-rw-r--r--protocol-wine/ftnoir_protocol_wine.h57
-rw-r--r--protocol-wine/ftnoir_protocol_wine_dialog.cpp19
-rw-r--r--protocol-wine/ftnoir_winecontrols.ui170
-rw-r--r--protocol-wine/images/wine.pngbin0 -> 376 bytes
-rw-r--r--protocol-wine/opentrack-wrapper-wine-main.cxx80
-rw-r--r--protocol-wine/opentrack-wrapper-wine-posix.cxx7
-rw-r--r--protocol-wine/opentrack-wrapper-wine-windows.cxx40
-rw-r--r--protocol-wine/wine-protocol.qrc5
-rw-r--r--protocol-wine/wine-shm.h20
11 files changed, 483 insertions, 0 deletions
diff --git a/protocol-wine/CMakeLists.txt b/protocol-wine/CMakeLists.txt
new file mode 100644
index 00000000..682e50de
--- /dev/null
+++ b/protocol-wine/CMakeLists.txt
@@ -0,0 +1,26 @@
+if(NOT WIN32)
+ set(SDK_WINE_PREFIX "" CACHE PATH "Wine install prefix")
+ set(SDK_WINE_NO_WRAPPER FALSE CACHE BOOL "disable Wine wrapper -- use Wine only for X-Plane")
+ if(SDK_WINE_PREFIX)
+ opentrack_boilerplate(opentrack-proto-wine)
+ target_link_libraries(opentrack-proto-wine opentrack-compat opentrack-csv)
+ if(NOT SDK_WINE_NO_WRAPPER)
+ set(my-rt -lrt)
+ if(APPLE)
+ set(my-rt)
+ endif()
+ file(GLOB wine-deps ${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/*.cxx)
+ add_custom_command(
+ OUTPUT opentrack-wrapper-wine.exe.so
+ DEPENDS ${wine-deps}
+ COMMAND ${SDK_WINE_PREFIX}/bin/wineg++ -g -DNOMINMAX -O2 -m32 -std=c++11 -o
+ opentrack-wrapper-wine.exe -I "${CMAKE_SOURCE_DIR}"
+ ${wine-deps}
+ ${my-rt})
+ add_custom_target(wine-wrapper ALL DEPENDS opentrack-wrapper-wine.exe.so)
+ add_dependencies(opentrack-proto-wine wine-wrapper)
+ add_dependencies(wine-wrapper opentrack-compat)
+ install(FILES "${CMAKE_BINARY_DIR}/opentrack-wrapper-wine.exe.so" DESTINATION .)
+ endif()
+ endif()
+endif()
diff --git a/protocol-wine/ftnoir_protocol_wine.cpp b/protocol-wine/ftnoir_protocol_wine.cpp
new file mode 100644
index 00000000..99ad30a2
--- /dev/null
+++ b/protocol-wine/ftnoir_protocol_wine.cpp
@@ -0,0 +1,59 @@
+#include "ftnoir_protocol_wine.h"
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h> /* For mode constants */
+#include <fcntl.h> /* For O_* constants */
+#include "csv/csv.h"
+
+FTNoIR_Protocol::FTNoIR_Protocol() : lck_shm(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)), shm(NULL), gameid(0)
+{
+ if (lck_shm.success()) {
+ shm = (WineSHM*) lck_shm.ptr();
+ memset(shm, 0, sizeof(*shm));
+ }
+ wrapper.start("wine", QStringList() << (QCoreApplication::applicationDirPath() + "/opentrack-wrapper-wine.exe.so"));
+}
+
+FTNoIR_Protocol::~FTNoIR_Protocol()
+{
+ if (shm) {
+ shm->stop = true;
+ wrapper.waitForFinished(100);
+ }
+ wrapper.terminate();
+ if (!wrapper.waitForFinished(100))
+ {
+ wrapper.kill();
+ wrapper.waitForFinished(42);
+ }
+ //shm_unlink("/" WINE_SHM_NAME);
+}
+
+void FTNoIR_Protocol::pose( const double *headpose ) {
+ if (shm)
+ {
+ lck_shm.lock();
+ for (int i = 3; i < 6; i++)
+ shm->data[i] = headpose[i] / 57.295781;
+ for (int i = 0; i < 3; i++)
+ shm->data[i] = headpose[i] * 10;
+ if (shm->gameid != gameid)
+ {
+ QString gamename;
+ QMutexLocker foo(&game_name_mutex);
+ /* only EZCA for FSX requires dummy process, and FSX doesn't work on Linux */
+ /* memory-hacks DLL can't be loaded into a Linux process, either */
+ CSV::getGameData(shm->gameid, shm->table, gamename);
+ gameid = shm->gameid2 = shm->gameid;
+ connected_game = gamename;
+ }
+ lck_shm.unlock();
+ }
+}
+
+bool FTNoIR_Protocol::correct()
+{
+ return lck_shm.success();
+}
+
+OPENTRACK_DECLARE_PROTOCOL(FTNoIR_Protocol, FTControls, FTNoIR_ProtocolDll)
diff --git a/protocol-wine/ftnoir_protocol_wine.h b/protocol-wine/ftnoir_protocol_wine.h
new file mode 100644
index 00000000..2aeb4608
--- /dev/null
+++ b/protocol-wine/ftnoir_protocol_wine.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include "ui_ftnoir_winecontrols.h"
+#include <QMessageBox>
+#include <QLibrary>
+#include <QProcess>
+#include <QDebug>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QFile>
+#include "opentrack/plugin-api.hpp"
+#include "opentrack-compat/shm.h"
+#include "ftnoir_protocol_wine/wine-shm.h"
+
+class FTNoIR_Protocol : public IProtocol
+{
+public:
+ FTNoIR_Protocol();
+ ~FTNoIR_Protocol() override;
+
+ bool correct() override;
+ void pose(const double* headpose) override;
+ QString game_name() override {
+ QMutexLocker foo(&game_name_mutex);
+ return connected_game;
+ }
+private:
+ PortableLockedShm lck_shm;
+ WineSHM* shm;
+ QProcess wrapper;
+ int gameid;
+ QString connected_game;
+ QMutex game_name_mutex;
+};
+
+class FTControls: public IProtocolDialog
+{
+ Q_OBJECT
+public:
+ FTControls();
+ void register_protocol(IProtocol *) override {}
+ void unregister_protocol() override {}
+
+private:
+ Ui::UICFTControls ui;
+
+private slots:
+ void doOK();
+ void doCancel();
+};
+
+class FTNoIR_ProtocolDll : public Metadata
+{
+public:
+ QString name() override { return QString("Wine -- Windows layer for Unix"); }
+ QIcon icon() override { return QIcon(":/images/wine.png"); }
+};
diff --git a/protocol-wine/ftnoir_protocol_wine_dialog.cpp b/protocol-wine/ftnoir_protocol_wine_dialog.cpp
new file mode 100644
index 00000000..e4027c73
--- /dev/null
+++ b/protocol-wine/ftnoir_protocol_wine_dialog.cpp
@@ -0,0 +1,19 @@
+#include "ftnoir_protocol_wine.h"
+#include <QDebug>
+#include "opentrack/plugin-api.hpp"
+
+FTControls::FTControls()
+{
+ ui.setupUi( this );
+ connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK()));
+ connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
+}
+
+void FTControls::doOK() {
+ this->close();
+}
+
+void FTControls::doCancel() {
+ this->close();
+}
+
diff --git a/protocol-wine/ftnoir_winecontrols.ui b/protocol-wine/ftnoir_winecontrols.ui
new file mode 100644
index 00000000..9356c448
--- /dev/null
+++ b/protocol-wine/ftnoir_winecontrols.ui
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICFTControls</class>
+ <widget class="QWidget" name="UICFTControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>409</width>
+ <height>110</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>FreeTrack settings FaceTrackNoIR</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>images/freetrack.png</normaloff>images/freetrack.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="_vertical_layout">
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>There are no settings necessary for the Wine protocol.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnOK">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/protocol-wine/images/wine.png b/protocol-wine/images/wine.png
new file mode 100644
index 00000000..bcf3a012
--- /dev/null
+++ b/protocol-wine/images/wine.png
Binary files differ
diff --git a/protocol-wine/opentrack-wrapper-wine-main.cxx b/protocol-wine/opentrack-wrapper-wine-main.cxx
new file mode 100644
index 00000000..ffe8938d
--- /dev/null
+++ b/protocol-wine/opentrack-wrapper-wine-main.cxx
@@ -0,0 +1,80 @@
+#include <cerrno>
+// OSX sdk 10.8 build error otherwise
+#ifdef _LIBCPP_MSVCRT
+# undef _LIBCPP_MSVCRT
+#endif
+#include <cstdio>
+#include "freetrackclient/fttypes.h"
+#include "ftnoir_protocol_wine/wine-shm.h"
+#include "opentrack-compat/export.hpp"
+
+enum Axis {
+ TX = 0, TY, TZ, Yaw, Pitch, Roll
+};
+
+#include "opentrack-compat/shm.h"
+
+void create_registry_key(void);
+
+class ShmPosix {
+public:
+ ShmPosix(const char *shmName, const char *mutexName, int mapSize);
+ ~ShmPosix();
+ void lock();
+ void unlock();
+ bool success();
+ inline void* ptr() { return mem; }
+private:
+ void* mem;
+ int fd, size;
+};
+
+class ShmWine {
+public:
+ ShmWine(const char *shmName, const char *mutexName, int mapSize);
+ ~ShmWine();
+ void lock();
+ void unlock();
+ bool success();
+ inline void* ptr() { return mem; }
+private:
+ void* mem;
+ void *hMutex, *hMapFile;
+};
+#include <windows.h>
+
+int main(void)
+{
+ ShmPosix lck_posix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM));
+ ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap));
+ if(!lck_posix.success()) {
+ printf("Can't open posix map: %d\n", errno);
+ return 1;
+ }
+ if(!lck_wine.success()) {
+ printf("Can't open Wine map\n");
+ return 1;
+ }
+ WineSHM* shm_posix = (WineSHM*) lck_posix.ptr();
+ FTHeap* shm_wine = (FTHeap*) lck_wine.ptr();
+ FTData* data = &shm_wine->data;
+ create_registry_key();
+ while (1) {
+ if (shm_posix->stop)
+ break;
+ data->Yaw = -shm_posix->data[Yaw];
+ data->Pitch = -shm_posix->data[Pitch];
+ data->Roll = shm_posix->data[Roll];
+ data->X = shm_posix->data[TX];
+ data->Y = shm_posix->data[TY];
+ data->Z = shm_posix->data[TZ];
+ data->DataID++;
+ data->CamWidth = 250;
+ data->CamHeight = 100;
+ shm_wine->GameID2 = shm_posix->gameid2;
+ shm_posix->gameid = shm_wine->GameID;
+ for (int i = 0; i < 8; i++)
+ shm_wine->table[i] = shm_posix->table[i];
+ (void) Sleep(4);
+ }
+}
diff --git a/protocol-wine/opentrack-wrapper-wine-posix.cxx b/protocol-wine/opentrack-wrapper-wine-posix.cxx
new file mode 100644
index 00000000..50cce728
--- /dev/null
+++ b/protocol-wine/opentrack-wrapper-wine-posix.cxx
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+# undef _WIN32
+#endif
+
+#define PortableLockedShm ShmPosix
+#include "opentrack-compat/shm.h"
+#include "opentrack-compat/shm.cpp"
diff --git a/protocol-wine/opentrack-wrapper-wine-windows.cxx b/protocol-wine/opentrack-wrapper-wine-windows.cxx
new file mode 100644
index 00000000..19ee8ffd
--- /dev/null
+++ b/protocol-wine/opentrack-wrapper-wine-windows.cxx
@@ -0,0 +1,40 @@
+#ifndef __WIN32
+# error "bad cross"
+#endif
+
+#define PortableLockedShm ShmWine
+#include "opentrack-compat/shm.h"
+#include "opentrack-compat/shm.cpp"
+#include "wine-shm.h"
+
+static void write_path(const char* key, const char* subkey)
+{
+ char dir[8192];
+
+ if (GetCurrentDirectoryA(8192, dir) < 8190)
+ {
+ HKEY hkpath;
+ if (RegCreateKeyExA(HKEY_CURRENT_USER,
+ key,
+ 0,
+ NULL,
+ 0,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hkpath,
+ NULL) == ERROR_SUCCESS)
+ {
+ for (int i = 0; dir[i]; i++)
+ if (dir[i] == '\\')
+ dir[i] = '/';
+ strcat(dir, "/");
+ (void) RegSetValueExA(hkpath, subkey, 0, REG_SZ, (BYTE*) dir, strlen(dir) + 1);
+ RegCloseKey(hkpath);
+ }
+ }
+}
+
+void create_registry_key(void) {
+ write_path("Software\\NaturalPoint\\NATURALPOINT\\NPClient Location", "Path");
+ write_path("Software\\Freetrack\\FreeTrackClient", "Path");
+}
diff --git a/protocol-wine/wine-protocol.qrc b/protocol-wine/wine-protocol.qrc
new file mode 100644
index 00000000..af81caea
--- /dev/null
+++ b/protocol-wine/wine-protocol.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/wine.png</file>
+ </qresource>
+</RCC>
diff --git a/protocol-wine/wine-shm.h b/protocol-wine/wine-shm.h
new file mode 100644
index 00000000..c7e29abb
--- /dev/null
+++ b/protocol-wine/wine-shm.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#define WINE_SHM_NAME "facetracknoir-wine-shm"
+#define WINE_MTX_NAME "facetracknoir-wine-mtx"
+
+// OSX sdk 10.8 build error otherwise
+#ifdef _LIBCPP_MSVCRT
+# undef _LIBCPP_MSVCRT
+#endif
+
+#include <memory>
+
+template<typename t> using ptr = std::shared_ptr<t>;
+
+struct WineSHM {
+ double data[6];
+ int gameid, gameid2;
+ unsigned char table[8];
+ bool stop;
+};