diff options
Diffstat (limited to 'protocol-sc')
| -rw-r--r-- | protocol-sc/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | protocol-sc/ftnoir-protocol-sc.rc | 4 | ||||
| -rw-r--r-- | protocol-sc/ftnoir_protocol_sc.cpp | 189 | ||||
| -rw-r--r-- | protocol-sc/ftnoir_protocol_sc.h | 108 | ||||
| -rw-r--r-- | protocol-sc/ftnoir_protocol_sc_dialog.cpp | 35 | ||||
| -rw-r--r-- | protocol-sc/ftnoir_sccontrols.ui | 72 | ||||
| -rw-r--r-- | protocol-sc/images/fsx.png | bin | 0 -> 813 bytes | |||
| -rw-r--r-- | protocol-sc/images/fsx1.png | bin | 0 -> 1920 bytes | |||
| -rw-r--r-- | protocol-sc/sc-protocol.qrc | 5 | ||||
| -rw-r--r-- | protocol-sc/scserver.manifest | 13 | ||||
| -rw-r--r-- | protocol-sc/scserver_acceleration.manifest | 13 | ||||
| -rw-r--r-- | protocol-sc/scserver_sp2.manifest | 13 | 
12 files changed, 455 insertions, 0 deletions
| diff --git a/protocol-sc/CMakeLists.txt b/protocol-sc/CMakeLists.txt new file mode 100644 index 00000000..bd83e944 --- /dev/null +++ b/protocol-sc/CMakeLists.txt @@ -0,0 +1,3 @@ +if(WIN32) +    opentrack_boilerplate(opentrack-proto-simconnect) +endif() diff --git a/protocol-sc/ftnoir-protocol-sc.rc b/protocol-sc/ftnoir-protocol-sc.rc new file mode 100644 index 00000000..c89eb9a7 --- /dev/null +++ b/protocol-sc/ftnoir-protocol-sc.rc @@ -0,0 +1,4 @@ +#include <winuser.h> +142 RT_MANIFEST scserver.manifest +143 RT_MANIFEST scserver_sp2.manifest +144 RT_MANIFEST scserver_acceleration.manifest
\ No newline at end of file diff --git a/protocol-sc/ftnoir_protocol_sc.cpp b/protocol-sc/ftnoir_protocol_sc.cpp new file mode 100644 index 00000000..0c6cb486 --- /dev/null +++ b/protocol-sc/ftnoir_protocol_sc.cpp @@ -0,0 +1,189 @@ +/* Homepage         http://facetracknoir.sourceforge.net/home/default.htm        * + *                                                                               * + * ISC License (ISC)                                                             * + *                                                                               * + * Copyright (c) 2015, Wim Vriend + * Copyright (c) 2014, Stanislaw Halik <sthalik@misaki.pl> + *                                                                               * + * Permission to use, copy, modify, and/or distribute this software for any      * + * 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_sc.h" +#include "opentrack/plugin-api.hpp" + +FTNoIR_Protocol::FTNoIR_Protocol() : should_stop(false), hSimConnect(nullptr) +{ +} + +FTNoIR_Protocol::~FTNoIR_Protocol() +{ +    should_stop = true; +    wait(); +} + +void FTNoIR_Protocol::run() +{ +    HANDLE event = CreateEvent(NULL, FALSE, FALSE, nullptr); + +    if (event == nullptr) +    { +        qDebug() << "simconnect: event create" << GetLastError(); +        return; +    } + +    while (!should_stop) +    { +        if (SUCCEEDED(simconnect_open(&hSimConnect, "opentrack", NULL, 0, event, 0))) +        { +            simconnect_subscribetosystemevent(hSimConnect, 0, "Frame"); + +            while (!should_stop) +            { +                if (WaitForSingleObject(event, 10) == WAIT_OBJECT_0) +                { +                    if (FAILED(simconnect_calldispatch(hSimConnect, processNextSimconnectEvent, reinterpret_cast<void*>(this)))) +                        break; +                } +            } + +            (void) simconnect_close(hSimConnect); +        } + +        if (!should_stop) +            Sleep(100); +    } + +    CloseHandle(event); +} + +void FTNoIR_Protocol::pose( const double *headpose ) { +    virtSCRotX = -headpose[Pitch];					// degrees +    virtSCRotY = headpose[Yaw]; +    virtSCRotZ = headpose[Roll]; + +    virtSCPosX = headpose[TX]/100.f;						// cm to meters +    virtSCPosY = headpose[TY]/100.f; +    virtSCPosZ = -headpose[TZ]/100.f; +} + +#ifdef __GNUC__ +#   pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +class ActivationContext { +public: +    ActivationContext(const int resid) : ok(false) { +        hactctx = INVALID_HANDLE_VALUE; +        actctx_cookie = 0; +        ACTCTXA actx = {0}; +        actx.cbSize = sizeof(ACTCTXA); +        actx.lpResourceName = MAKEINTRESOURCEA(resid); +        actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; +#ifdef _MSC_VER +#	define PREFIX "" +#else +#	define PREFIX "lib" +#endif +        QString path = QCoreApplication::applicationDirPath() + "/" PREFIX "opentrack-proto-simconnect.dll"; +        QByteArray name = QFile::encodeName(path); +        actx.lpSource = name.constData(); +        hactctx = CreateActCtxA(&actx); +        actctx_cookie = 0; +        if (hactctx != INVALID_HANDLE_VALUE) { +            if (!ActivateActCtx(hactctx, &actctx_cookie)) { +                qDebug() << "SC: can't set win32 activation context" << GetLastError(); +                ReleaseActCtx(hactctx); +                hactctx = INVALID_HANDLE_VALUE; +            } +            else +                ok = true; +        } else { +            qDebug() << "SC: can't create win32 activation context" << GetLastError(); +        } +    } +    ~ActivationContext() { +        if (hactctx != INVALID_HANDLE_VALUE) +        { +            DeactivateActCtx(0, actctx_cookie); +            ReleaseActCtx(hactctx); +        } +    } +    bool is_ok() { return ok; } +private: +    ULONG_PTR actctx_cookie; +    HANDLE hactctx; +    bool ok; +}; + +bool FTNoIR_Protocol::correct() +{ +    if (!SCClientLib.isLoaded()) +    { +        ActivationContext ctx(142 + static_cast<int>(s.sxs_manifest)); + +        if (ctx.is_ok()) +        { +            SCClientLib.setFileName("SimConnect.dll"); +            if (!SCClientLib.load()) { +                qDebug() << "SC load" << SCClientLib.errorString(); +                return false; +            } +        } +        else +            return false; +    } + +	simconnect_open = (importSimConnect_Open) SCClientLib.resolve("SimConnect_Open"); +	if (simconnect_open == NULL) { +		qDebug() << "FTNoIR_Protocol::correct() says: SimConnect_Open function not found in DLL!"; +		return false; +	} +	simconnect_set6DOF = (importSimConnect_CameraSetRelative6DOF) SCClientLib.resolve("SimConnect_CameraSetRelative6DOF"); +	if (simconnect_set6DOF == NULL) { +		qDebug() << "FTNoIR_Protocol::correct() says: SimConnect_CameraSetRelative6DOF function not found in DLL!"; +		return false; +	} +	simconnect_close = (importSimConnect_Close) SCClientLib.resolve("SimConnect_Close"); +	if (simconnect_close == NULL) { +		qDebug() << "FTNoIR_Protocol::correct() says: SimConnect_Close function not found in DLL!"; +		return false; +	} + +	simconnect_calldispatch = (importSimConnect_CallDispatch) SCClientLib.resolve("SimConnect_CallDispatch"); +	if (simconnect_calldispatch == NULL) { +		qDebug() << "FTNoIR_Protocol::correct() says: SimConnect_CallDispatch function not found in DLL!"; +		return false; +	} + +	simconnect_subscribetosystemevent = (importSimConnect_SubscribeToSystemEvent) SCClientLib.resolve("SimConnect_SubscribeToSystemEvent"); +	if (simconnect_subscribetosystemevent == NULL) { +		qDebug() << "FTNoIR_Protocol::correct() says: SimConnect_SubscribeToSystemEvent function not found in DLL!"; +		return false; +	} + +    start(); + +	return true; +} + +void FTNoIR_Protocol::handle() +{ +    (void) simconnect_set6DOF(hSimConnect, virtSCPosX, virtSCPosY, virtSCPosZ, virtSCRotX, virtSCRotZ, virtSCRotY); +} + +void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD, void *self_) +{ +    FTNoIR_Protocol& self = *reinterpret_cast<FTNoIR_Protocol*>(self_); + +    switch(pData->dwID) +    { +    default: +        break; +    case SIMCONNECT_RECV_ID_EVENT_FRAME: +        self.handle(); +        break; +    } +} + +OPENTRACK_DECLARE_PROTOCOL(FTNoIR_Protocol, SCControls, FTNoIR_ProtocolDll) diff --git a/protocol-sc/ftnoir_protocol_sc.h b/protocol-sc/ftnoir_protocol_sc.h new file mode 100644 index 00000000..671a3500 --- /dev/null +++ b/protocol-sc/ftnoir_protocol_sc.h @@ -0,0 +1,108 @@ +/* Homepage         http://facetracknoir.sourceforge.net/home/default.htm        * + *                                                                               * + * ISC License (ISC)                                                             * + *                                                                               * + * Copyright (c) 2015, Wim Vriend                                                * + * Copyright (c) 2014, Stanislaw Halik                                           * + *                                                                               * + * Permission to use, copy, modify, and/or distribute this software for any      * + * purpose with or without fee is hereby granted, provided that the above        * + * copyright notice and this permission notice appear in all copies.             * + */ +#pragma once +#include "opentrack/plugin-api.hpp" + +#include "ui_ftnoir_sccontrols.h" +#include <QThread> +#include <QMessageBox> +#include <QSettings> +#include <QLibrary> +#include <QProcess> +#include <QDebug> +#include <QFile> +#include "opentrack/options.hpp" +using namespace options; +#include <windows.h> + +struct settings : opts { +    value<int> sxs_manifest; +    settings() : +        opts("proto-simconnect"), +        sxs_manifest(b, "sxs-manifest-version", 0) +    {} +}; + +class FTNoIR_Protocol : public IProtocol, private QThread +{ +public: +    FTNoIR_Protocol(); +    ~FTNoIR_Protocol() override; +    bool correct(); +    void pose(const double* headpose); +    void handle(); +    QString game_name() { +        return "FS2004/FSX"; +    } +private: +    enum { SIMCONNECT_RECV_ID_EVENT_FRAME = 7 }; + +    #pragma pack(push, 1) +    struct SIMCONNECT_RECV +    { +        DWORD   dwSize; +        DWORD   dwVersion; +        DWORD   dwID; +    }; +    #pragma pack(pop) + +    typedef void (CALLBACK *DispatchProc)(SIMCONNECT_RECV*, DWORD, void*); + +    typedef HRESULT (WINAPI *importSimConnect_Open)(HANDLE * phSimConnect, LPCSTR szName, HWND hWnd, DWORD UserEventWin32, HANDLE hEventHandle, DWORD ConfigIndex); +    typedef HRESULT (WINAPI *importSimConnect_Close)(HANDLE hSimConnect); +    typedef HRESULT (WINAPI *importSimConnect_CameraSetRelative6DOF)(HANDLE hSimConnect, float fDeltaX, float fDeltaY, float fDeltaZ, float fPitchDeg, float fBankDeg, float fHeadingDeg); +    typedef HRESULT (WINAPI *importSimConnect_CallDispatch)(HANDLE hSimConnect, DispatchProc pfcnDispatch, void * pContext); +    typedef HRESULT (WINAPI *importSimConnect_SubscribeToSystemEvent)(HANDLE hSimConnect, DWORD EventID, const char * SystemEventName); + +    void run() override; +    volatile bool should_stop; + +    volatile float virtSCPosX; +    volatile float virtSCPosY; +    volatile float virtSCPosZ; +    volatile float virtSCRotX; +    volatile float virtSCRotY; +    volatile float virtSCRotZ; + +    importSimConnect_Open simconnect_open; +    importSimConnect_Close simconnect_close; +    importSimConnect_CameraSetRelative6DOF simconnect_set6DOF; +    importSimConnect_CallDispatch simconnect_calldispatch; +    importSimConnect_SubscribeToSystemEvent simconnect_subscribetosystemevent; + +    HANDLE hSimConnect; +    static void CALLBACK processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext); +    settings s; +    QLibrary SCClientLib; +}; + +class SCControls: public IProtocolDialog +{ +    Q_OBJECT +public: +    SCControls(); +    void register_protocol(IProtocol *) {} +    void unregister_protocol() {} +private: +    Ui::UICSCControls ui; +    settings s; +private slots: +    void doOK(); +    void doCancel(); +}; + +class FTNoIR_ProtocolDll : public Metadata +{ +public: +    QString name() { return QString("Microsoft FSX SimConnect"); } +    QIcon icon() { return QIcon(":/images/fsx.png"); } +}; diff --git a/protocol-sc/ftnoir_protocol_sc_dialog.cpp b/protocol-sc/ftnoir_protocol_sc_dialog.cpp new file mode 100644 index 00000000..7c2ecfd4 --- /dev/null +++ b/protocol-sc/ftnoir_protocol_sc_dialog.cpp @@ -0,0 +1,35 @@ +/* Homepage         http://facetracknoir.sourceforge.net/home/default.htm        * + *                                                                               * + * ISC License (ISC)                                                             * + *                                                                               * + * Copyright (c) 2015, Wim Vriend                                                * + *                                                                               * + * Permission to use, copy, modify, and/or distribute this software for any      * + * 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_sc.h" +#include <QDebug> +#include "opentrack/plugin-api.hpp" + +SCControls::SCControls() +{ +	ui.setupUi( this ); + +	// Connect Qt signals to member-functions +    connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); +    connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); + +    tie_setting(s.sxs_manifest, ui.comboBox); +} + +void SCControls::doOK() { +    s.b->save(); +	this->close(); +} + +void SCControls::doCancel() { +    s.b->reload(); +    close(); +} + diff --git a/protocol-sc/ftnoir_sccontrols.ui b/protocol-sc/ftnoir_sccontrols.ui new file mode 100644 index 00000000..5b2fd291 --- /dev/null +++ b/protocol-sc/ftnoir_sccontrols.ui @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICSCControls</class> + <widget class="QWidget" name="UICSCControls"> +  <property name="windowModality"> +   <enum>Qt::NonModal</enum> +  </property> +  <property name="geometry"> +   <rect> +    <x>0</x> +    <y>0</y> +    <width>290</width> +    <height>79</height> +   </rect> +  </property> +  <property name="windowTitle"> +   <string>SimConnect settings FaceTrackNoIR</string> +  </property> +  <property name="windowIcon"> +   <iconset> +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset> +  </property> +  <property name="layoutDirection"> +   <enum>Qt::LeftToRight</enum> +  </property> +  <property name="autoFillBackground"> +   <bool>false</bool> +  </property> +  <layout class="QGridLayout" name="gridLayout"> +   <item row="0" column="0"> +    <widget class="QLabel" name="label"> +     <property name="text"> +      <string>FSX version</string> +     </property> +    </widget> +   </item> +   <item row="0" column="1"> +    <widget class="QComboBox" name="comboBox"> +     <item> +      <property name="text"> +       <string>SP1</string> +      </property> +     </item> +     <item> +      <property name="text"> +       <string>SP2</string> +      </property> +     </item> +     <item> +      <property name="text"> +       <string>Acceleration</string> +      </property> +     </item> +    </widget> +   </item> +   <item row="1" column="1"> +    <widget class="QDialogButtonBox" name="buttonBox"> +     <property name="standardButtons"> +      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> +     </property> +    </widget> +   </item> +  </layout> + </widget> + <resources/> + <connections/> + <slots> +  <slot>startEngineClicked()</slot> +  <slot>stopEngineClicked()</slot> +  <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/protocol-sc/images/fsx.png b/protocol-sc/images/fsx.pngBinary files differ new file mode 100644 index 00000000..16b072a1 --- /dev/null +++ b/protocol-sc/images/fsx.png diff --git a/protocol-sc/images/fsx1.png b/protocol-sc/images/fsx1.pngBinary files differ new file mode 100644 index 00000000..a1f0f188 --- /dev/null +++ b/protocol-sc/images/fsx1.png diff --git a/protocol-sc/sc-protocol.qrc b/protocol-sc/sc-protocol.qrc new file mode 100644 index 00000000..127d5180 --- /dev/null +++ b/protocol-sc/sc-protocol.qrc @@ -0,0 +1,5 @@ +<RCC> +    <qresource prefix="/"> +        <file>images/fsx.png</file> +    </qresource> +</RCC> diff --git a/protocol-sc/scserver.manifest b/protocol-sc/scserver.manifest new file mode 100644 index 00000000..d342cfda --- /dev/null +++ b/protocol-sc/scserver.manifest @@ -0,0 +1,13 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> +  <dependency> +    <dependentAssembly> +      <assemblyIdentity type='win32' name='Microsoft.FlightSimulator.SimConnect' version='10.0.61259.0' processorArchitecture='x86' publicKeyToken='67c7c14424d61b5b' /> +    </dependentAssembly> +  </dependency> +  <dependency> +    <dependentAssembly> +      <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> +    </dependentAssembly> +  </dependency> +</assembly> diff --git a/protocol-sc/scserver_acceleration.manifest b/protocol-sc/scserver_acceleration.manifest new file mode 100644 index 00000000..06459587 --- /dev/null +++ b/protocol-sc/scserver_acceleration.manifest @@ -0,0 +1,13 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> +  <dependency> +    <dependentAssembly> +      <assemblyIdentity type='win32' name='Microsoft.FlightSimulator.SimConnect ' version='10.0.61242.0' processorArchitecture='x86' publicKeyToken='67c7c14424d61b5b' /> +    </dependentAssembly> +  </dependency> +  <dependency> +    <dependentAssembly> +      <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> +    </dependentAssembly> +  </dependency> +</assembly> diff --git a/protocol-sc/scserver_sp2.manifest b/protocol-sc/scserver_sp2.manifest new file mode 100644 index 00000000..3020d16c --- /dev/null +++ b/protocol-sc/scserver_sp2.manifest @@ -0,0 +1,13 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> +  <dependency> +    <dependentAssembly> +      <assemblyIdentity type='win32' name='Microsoft.FlightSimulator.SimConnect ' version='10.0.60905.0' processorArchitecture='x86' publicKeyToken='67c7c14424d61b5b' /> +    </dependentAssembly> +  </dependency> +  <dependency> +    <dependentAssembly> +      <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> +    </dependentAssembly> +  </dependency> +</assembly> | 
