mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-20 20:40:29 +08:00
refs #279, FSUIPC support
This commit is contained in:
@@ -12,6 +12,7 @@ blackcore {
|
|||||||
win32 {
|
win32 {
|
||||||
contains(BLACK_CONFIG, FSX) {
|
contains(BLACK_CONFIG, FSX) {
|
||||||
LIBS += -lSimConnect
|
LIBS += -lSimConnect
|
||||||
|
LIBS += -lFSUIPC_User
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
51
src/plugins/simulator/fsx/fsuipc.cpp
Normal file
51
src/plugins/simulator/fsx/fsuipc.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
src/plugins/simulator/fsx/fsuipc.h
Normal file
84
src/plugins/simulator/fsx/fsuipc.h
Normal 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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user