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 {
contains(BLACK_CONFIG, FSX) {
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 += blackmisc blackcore blacksim
LIBS += -lSimConnect
LIBS += -lSimConnect -lFSUIPC_User
# required for FSUIPC
win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib
DEPENDPATH += . ../../../../src
INCLUDEPATH += . ../../../../src

View File

@@ -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<bool> result = QtConcurrent::run(asyncConnectFunc);
QFuture<bool> 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<int>(requestID); });
[requestID](const CSimConnectObject & obj) { return obj.getRequestId() == static_cast<int>(requestID); });
if (it == m_simConnectObjects.end())
return;

View File

@@ -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<bool> m_watcherConnect;
QScopedPointer<CFsuipc> m_fsuipc;
};
}