refs #279, FSUIPC support

This commit is contained in:
Klaus Basan
2014-06-20 00:41:06 +02:00
parent 0a6f711e82
commit c404d4cc5b
6 changed files with 167 additions and 8 deletions

View File

@@ -12,6 +12,7 @@ blackcore {
win32 { win32 {
contains(BLACK_CONFIG, FSX) { contains(BLACK_CONFIG, FSX) {
LIBS += -lSimConnect LIBS += -lSimConnect
LIBS += -lFSUIPC_User
} }
} }
} }

View File

@@ -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 <Windows.h>
// bug in FSUIPC_User.h, windows.h not included, so we have to import it first
#include "FSUIPC/FSUIPC_User.h"
#include <QDebug>
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<int>(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;
}
}
}

View File

@@ -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 <QStringList>
// 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

View File

@@ -9,7 +9,10 @@ TEMPLATE = lib
CONFIG += plugin shared CONFIG += plugin shared
CONFIG += blackmisc blackcore blacksim CONFIG += blackmisc blackcore blacksim
LIBS += -lSimConnect LIBS += -lSimConnect -lFSUIPC_User
# required for FSUIPC
win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib
DEPENDPATH += . ../../../../src DEPENDPATH += . ../../../../src
INCLUDEPATH += . ../../../../src INCLUDEPATH += . ../../../../src

View File

@@ -45,7 +45,8 @@ namespace BlackSimPlugin
m_nextObjID(1), m_nextObjID(1),
m_simulatorInfo(CSimulatorInfo::FSX()), m_simulatorInfo(CSimulatorInfo::FSX()),
m_simconnectTimerId(-1), m_simconnectTimerId(-1),
m_skipCockpitUpdateCycles(0) m_skipCockpitUpdateCycles(0),
m_fsuipc(new CFsuipc())
{ {
CFsxSimulatorSetup setup; CFsxSimulatorSetup setup;
setup.init(); // this fetches important setting on local side setup.init(); // this fetches important setting on local side
@@ -62,15 +63,25 @@ namespace BlackSimPlugin
return m_isConnected; return m_isConnected;
} }
bool CSimulatorFsx::isFsuipcConnected() const
{
return m_fsuipc->isConnected();
}
bool CSimulatorFsx::connectTo() bool CSimulatorFsx::connectTo()
{ {
if (m_isConnected) if (m_isConnected) return true;
return true;
if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0)))
{ {
emit statusChanged(ConnectionFailed);
return false; return false;
} }
else
{
this->m_fsuipc->connect(); // connect FSUIPC too
}
initEvents(); initEvents();
initDataDefinitions(); initDataDefinitions();
@@ -85,13 +96,15 @@ namespace BlackSimPlugin
{ {
connect(&m_watcherConnect, SIGNAL(finished()), this, SLOT(connectToFinished())); connect(&m_watcherConnect, SIGNAL(finished()), this, SLOT(connectToFinished()));
// simplified connect, timers and signals not in different thread
auto asyncConnectFunc = [&]() -> bool auto asyncConnectFunc = [&]() -> bool
{ {
if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) return false; if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) return false;
this->m_fsuipc->connect(); // FSUIPC too
return true; return true;
}; };
QFuture<bool> result = QtConcurrent::run(asyncConnectFunc);
QFuture<bool> result = QtConcurrent::run(asyncConnectFunc);
m_watcherConnect.setFuture(result); m_watcherConnect.setFuture(result);
} }
@@ -102,8 +115,10 @@ namespace BlackSimPlugin
emit statusChanged(Disconnected); emit statusChanged(Disconnected);
if (m_hSimConnect) if (m_hSimConnect)
{
SimConnect_Close(m_hSimConnect); SimConnect_Close(m_hSimConnect);
this->m_fsuipc->disconnect();
}
if (m_simconnectTimerId) if (m_simconnectTimerId)
killTimer(m_simconnectTimerId); killTimer(m_simconnectTimerId);
@@ -435,7 +450,7 @@ namespace BlackSimPlugin
{ {
// First check, if this request id belongs to us // First check, if this request id belongs to us
auto it = std::find_if(m_simConnectObjects.begin(), m_simConnectObjects.end(), auto it = std::find_if(m_simConnectObjects.begin(), m_simConnectObjects.end(),
[requestID](const CSimConnectObject &obj) { return obj.getRequestId() == static_cast<int>(requestID); }); [requestID](const CSimConnectObject & obj) { return obj.getRequestId() == static_cast<int>(requestID); });
if (it == m_simConnectObjects.end()) if (it == m_simConnectObjects.end())
return; return;

View File

@@ -8,6 +8,7 @@
#include "simconnect_datadefinition.h" #include "simconnect_datadefinition.h"
#include "simconnect_object.h" #include "simconnect_object.h"
#include "fsuipc.h"
#include "blackcore/simulator.h" #include "blackcore/simulator.h"
#include "blackcore/interpolator_linear.h" #include "blackcore/interpolator_linear.h"
#include "blackmisc/avaircraft.h" #include "blackmisc/avaircraft.h"
@@ -78,6 +79,9 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::isConnected() //! \copydoc ISimulator::isConnected()
virtual bool isConnected() const override; virtual bool isConnected() const override;
//! FSUIPC connected?
bool isFsuipcConnected() const;
//! \copydoc ISimulator::canConnect() //! \copydoc ISimulator::canConnect()
virtual bool canConnect() override; virtual bool canConnect() override;
@@ -172,7 +176,7 @@ namespace BlackSimPlugin
//! Update what? //! Update what?
void update(); // TODO: @RW, please rename, update is meaningless: what is updated? 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_isConnected; //!< Is simulator connected?
bool m_simRunning; //!< Simulator running? bool m_simRunning; //!< Simulator running?
HANDLE m_hSimConnect; //!< Handle to SimConnect object HANDLE m_hSimConnect; //!< Handle to SimConnect object
@@ -186,6 +190,7 @@ namespace BlackSimPlugin
int m_simconnectTimerId; int m_simconnectTimerId;
int m_skipCockpitUpdateCycles; //!< Skip some update cycles to allow changes in simulator cockpit to be set int m_skipCockpitUpdateCycles; //!< Skip some update cycles to allow changes in simulator cockpit to be set
QFutureWatcher<bool> m_watcherConnect; QFutureWatcher<bool> m_watcherConnect;
QScopedPointer<CFsuipc> m_fsuipc;
}; };
} }