diff options
Diffstat (limited to 'proto-wine')
-rw-r--r-- | proto-wine/CMakeLists.txt | 26 | ||||
-rw-r--r-- | proto-wine/ftnoir_protocol_wine.cpp | 59 | ||||
-rw-r--r-- | proto-wine/ftnoir_protocol_wine.h | 57 | ||||
-rw-r--r-- | proto-wine/ftnoir_protocol_wine_dialog.cpp | 19 | ||||
-rw-r--r-- | proto-wine/ftnoir_winecontrols.ui | 170 | ||||
-rw-r--r-- | proto-wine/images/wine.png | bin | 0 -> 376 bytes | |||
-rw-r--r-- | proto-wine/opentrack-wrapper-wine-main.cxx | 80 | ||||
-rw-r--r-- | proto-wine/opentrack-wrapper-wine-posix.cxx | 7 | ||||
-rw-r--r-- | proto-wine/opentrack-wrapper-wine-windows.cxx | 40 | ||||
-rw-r--r-- | proto-wine/wine-protocol.qrc | 5 | ||||
-rw-r--r-- | proto-wine/wine-shm.h | 20 |
11 files changed, 483 insertions, 0 deletions
diff --git a/proto-wine/CMakeLists.txt b/proto-wine/CMakeLists.txt new file mode 100644 index 00000000..bafcff8b --- /dev/null +++ b/proto-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 ${PROJECT_SOURCE_DIR}/*.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/proto-wine/ftnoir_protocol_wine.cpp b/proto-wine/ftnoir_protocol_wine.cpp new file mode 100644 index 00000000..99ad30a2 --- /dev/null +++ b/proto-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/proto-wine/ftnoir_protocol_wine.h b/proto-wine/ftnoir_protocol_wine.h new file mode 100644 index 00000000..f78e1364 --- /dev/null +++ b/proto-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 "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/proto-wine/ftnoir_protocol_wine_dialog.cpp b/proto-wine/ftnoir_protocol_wine_dialog.cpp new file mode 100644 index 00000000..e4027c73 --- /dev/null +++ b/proto-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/proto-wine/ftnoir_winecontrols.ui b/proto-wine/ftnoir_winecontrols.ui new file mode 100644 index 00000000..9356c448 --- /dev/null +++ b/proto-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/proto-wine/images/wine.png b/proto-wine/images/wine.png Binary files differnew file mode 100644 index 00000000..bcf3a012 --- /dev/null +++ b/proto-wine/images/wine.png diff --git a/proto-wine/opentrack-wrapper-wine-main.cxx b/proto-wine/opentrack-wrapper-wine-main.cxx new file mode 100644 index 00000000..082e5dde --- /dev/null +++ b/proto-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 "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/proto-wine/opentrack-wrapper-wine-posix.cxx b/proto-wine/opentrack-wrapper-wine-posix.cxx new file mode 100644 index 00000000..50cce728 --- /dev/null +++ b/proto-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/proto-wine/opentrack-wrapper-wine-windows.cxx b/proto-wine/opentrack-wrapper-wine-windows.cxx new file mode 100644 index 00000000..19ee8ffd --- /dev/null +++ b/proto-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/proto-wine/wine-protocol.qrc b/proto-wine/wine-protocol.qrc new file mode 100644 index 00000000..af81caea --- /dev/null +++ b/proto-wine/wine-protocol.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>images/wine.png</file> + </qresource> +</RCC> diff --git a/proto-wine/wine-shm.h b/proto-wine/wine-shm.h new file mode 100644 index 00000000..c7e29abb --- /dev/null +++ b/proto-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; +}; |