From c404d4cc5b1a5b20fe2b2ef4f975e7019ec1e275 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 20 Jun 2014 00:41:06 +0200 Subject: [PATCH] refs #279, FSUIPC support --- libraries.pri | 1 + src/plugins/simulator/fsx/fsuipc.cpp | 51 +++++++++++++ src/plugins/simulator/fsx/fsuipc.h | 84 +++++++++++++++++++++ src/plugins/simulator/fsx/plugin_fsx.pro | 5 +- src/plugins/simulator/fsx/simulator_fsx.cpp | 27 +++++-- src/plugins/simulator/fsx/simulator_fsx.h | 7 +- 6 files changed, 167 insertions(+), 8 deletions(-) create mode 100644 src/plugins/simulator/fsx/fsuipc.cpp create mode 100644 src/plugins/simulator/fsx/fsuipc.h diff --git a/libraries.pri b/libraries.pri index 39df0342a..c43bf8afe 100644 --- a/libraries.pri +++ b/libraries.pri @@ -12,6 +12,7 @@ blackcore { win32 { contains(BLACK_CONFIG, FSX) { LIBS += -lSimConnect + LIBS += -lFSUIPC_User } } } diff --git a/src/plugins/simulator/fsx/fsuipc.cpp b/src/plugins/simulator/fsx/fsuipc.cpp new file mode 100644 index 000000000..cac6aceb0 --- /dev/null +++ b/src/plugins/simulator/fsx/fsuipc.cpp @@ -0,0 +1,51 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "fsuipc.h" +#include +// bug in FSUIPC_User.h, windows.h not included, so we have to import it first +#include "FSUIPC/FSUIPC_User.h" +#include + +namespace BlackSimPlugin +{ + namespace Fsx + { + + CFsuipc::CFsuipc() : m_connected(false) + { } + + CFsuipc::~CFsuipc() + { + this->disconnect(); + } + + bool CFsuipc::connect() + { + DWORD result; + this->m_lastErrorMessage = ""; + if (this->m_connected) return this->m_connected; // already connected + if (FSUIPC_Open(SIM_ANY, &result)) + { + this->m_connected = true; + qDebug() << "FSUIPC connected"; + } + else + { + this->m_connected = false; + int index = static_cast(result); + this->m_lastErrorMessage = CFsuipc::errorMessages().at(index); + qDebug() << "FSUIPC" << this->m_lastErrorMessage; + } + return this->m_connected; + } + + void CFsuipc::disconnect() + { + FSUIPC_Close(); // Closing when it wasn't open is okay, so this is safe here + this->m_connected = false; + } + } +} diff --git a/src/plugins/simulator/fsx/fsuipc.h b/src/plugins/simulator/fsx/fsuipc.h new file mode 100644 index 000000000..35f5351dc --- /dev/null +++ b/src/plugins/simulator/fsx/fsuipc.h @@ -0,0 +1,84 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BLACKSIMPLUGIN_FSUIPC_H +#define BLACKSIMPLUGIN_FSUIPC_H + +#include + +// SB offsets +// http://board.vacc-sag.org/32/7945/#post75582 +// http://squawkbox.ca/doc/sdk/fsuipc.php + +namespace BlackSimPlugin +{ + namespace Fsx + { + //! Class representing a SimConnect object + class CFsuipc + { + public: + + //! Constructor + CFsuipc(); + + //! Destructor + ~CFsuipc(); + + //! Open conenction with FSUIPC + bool connect(); + + //! Disconnect + void disconnect(); + + //! Is connected? + bool isConnected() const { return m_connected; } + + //! Error messages + static const QStringList &errorMessages() + { + static const QStringList errors( + { + "Okay", + "Attempt to Open when already Open", + "Cannot link to FSUIPC or WideClient", + "Failed to Register common message with Windows", + "Failed to create Atom for mapping filename", + "Failed to create a file mapping object", + "Failed to open a view to the file map", + "Incorrect version of FSUIPC, or not FSUIPC", + "Sim is not version requested", + "Call cannot execute, link not Open", + "Call cannot execute: no requests accumulated", + "IPC timed out all retries", + "IPC sendmessage failed all retries", + "IPC request contains bad data", + "Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC", + "Read or Write request cannot be added, memory for Process is full", + } + ); + return errors; + } + + //! Simulators + static const QStringList &simulators() + { + static const QStringList sims( + { + "FS98", "FS2000", "CFS2", "CFS1", "Fly!", "FS2002", "FS2004" + } + ); + return sims; + } + + private: + bool m_connected; + QString m_lastErrorMessage; + + }; + } +} + +#endif // guard diff --git a/src/plugins/simulator/fsx/plugin_fsx.pro b/src/plugins/simulator/fsx/plugin_fsx.pro index 64e0562e2..33a03d3fc 100644 --- a/src/plugins/simulator/fsx/plugin_fsx.pro +++ b/src/plugins/simulator/fsx/plugin_fsx.pro @@ -9,7 +9,10 @@ TEMPLATE = lib CONFIG += plugin shared CONFIG += blackmisc blackcore blacksim -LIBS += -lSimConnect +LIBS += -lSimConnect -lFSUIPC_User + +# required for FSUIPC +win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib DEPENDPATH += . ../../../../src INCLUDEPATH += . ../../../../src diff --git a/src/plugins/simulator/fsx/simulator_fsx.cpp b/src/plugins/simulator/fsx/simulator_fsx.cpp index 83fdeb294..7cd4b5d79 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx.cpp @@ -45,7 +45,8 @@ namespace BlackSimPlugin m_nextObjID(1), m_simulatorInfo(CSimulatorInfo::FSX()), m_simconnectTimerId(-1), - m_skipCockpitUpdateCycles(0) + m_skipCockpitUpdateCycles(0), + m_fsuipc(new CFsuipc()) { CFsxSimulatorSetup setup; setup.init(); // this fetches important setting on local side @@ -62,15 +63,25 @@ namespace BlackSimPlugin return m_isConnected; } + bool CSimulatorFsx::isFsuipcConnected() const + { + return m_fsuipc->isConnected(); + } + + bool CSimulatorFsx::connectTo() { - if (m_isConnected) - return true; + if (m_isConnected) return true; if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) { + emit statusChanged(ConnectionFailed); return false; } + else + { + this->m_fsuipc->connect(); // connect FSUIPC too + } initEvents(); initDataDefinitions(); @@ -85,13 +96,15 @@ namespace BlackSimPlugin { connect(&m_watcherConnect, SIGNAL(finished()), this, SLOT(connectToFinished())); + // simplified connect, timers and signals not in different thread auto asyncConnectFunc = [&]() -> bool { if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) return false; + this->m_fsuipc->connect(); // FSUIPC too return true; }; - QFuture result = QtConcurrent::run(asyncConnectFunc); + QFuture result = QtConcurrent::run(asyncConnectFunc); m_watcherConnect.setFuture(result); } @@ -102,8 +115,10 @@ namespace BlackSimPlugin emit statusChanged(Disconnected); if (m_hSimConnect) + { SimConnect_Close(m_hSimConnect); - + this->m_fsuipc->disconnect(); + } if (m_simconnectTimerId) killTimer(m_simconnectTimerId); @@ -435,7 +450,7 @@ namespace BlackSimPlugin { // First check, if this request id belongs to us auto it = std::find_if(m_simConnectObjects.begin(), m_simConnectObjects.end(), - [requestID](const CSimConnectObject &obj) { return obj.getRequestId() == static_cast(requestID); }); + [requestID](const CSimConnectObject & obj) { return obj.getRequestId() == static_cast(requestID); }); if (it == m_simConnectObjects.end()) return; diff --git a/src/plugins/simulator/fsx/simulator_fsx.h b/src/plugins/simulator/fsx/simulator_fsx.h index 603474c0d..23c5fe4b2 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.h +++ b/src/plugins/simulator/fsx/simulator_fsx.h @@ -8,6 +8,7 @@ #include "simconnect_datadefinition.h" #include "simconnect_object.h" +#include "fsuipc.h" #include "blackcore/simulator.h" #include "blackcore/interpolator_linear.h" #include "blackmisc/avaircraft.h" @@ -78,6 +79,9 @@ namespace BlackSimPlugin //! \copydoc ISimulator::isConnected() virtual bool isConnected() const override; + //! FSUIPC connected? + bool isFsuipcConnected() const; + //! \copydoc ISimulator::canConnect() virtual bool canConnect() override; @@ -172,7 +176,7 @@ namespace BlackSimPlugin //! Update what? void update(); // TODO: @RW, please rename, update is meaningless: what is updated? - static const int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles for updating cockpit again + static const int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again bool m_isConnected; //!< Is simulator connected? bool m_simRunning; //!< Simulator running? HANDLE m_hSimConnect; //!< Handle to SimConnect object @@ -186,6 +190,7 @@ namespace BlackSimPlugin int m_simconnectTimerId; int m_skipCockpitUpdateCycles; //!< Skip some update cycles to allow changes in simulator cockpit to be set QFutureWatcher m_watcherConnect; + QScopedPointer m_fsuipc; }; }