refs #358, added (a first very simple) model matching to FSX driver

* isRunning → isSimulating
* adjusted addRemoteAircraft signature (remark: CClient as parameter will be removed)
* renamed to "ownAircraft" when referring to own aircraft
* functions to access installed models/matched models
* model matching in CSimulatorFsx::addRemoteAircraft
This commit is contained in:
Klaus Basan
2014-12-28 20:33:11 +01:00
parent c285ac4098
commit 23e9159dfd
11 changed files with 324 additions and 212 deletions

View File

@@ -16,6 +16,6 @@ namespace BlackCore
void ISimulator::emitSimulatorCombinedStatus() void ISimulator::emitSimulatorCombinedStatus()
{ {
emit simulatorStatusChanged(isConnected(), isRunning(), isPaused()); emit simulatorStatusChanged(isConnected(), isSimulating(), isPaused());
} }
} // namespace } // namespace

View File

@@ -18,6 +18,7 @@
#include "blackmisc/avairportlist.h" #include "blackmisc/avairportlist.h"
#include "blackmisc/nwaircraftmodellist.h" #include "blackmisc/nwaircraftmodellist.h"
#include "blackmisc/nwtextmessage.h" #include "blackmisc/nwtextmessage.h"
#include "blackmisc/nwclient.h"
#include <QObject> #include <QObject>
namespace BlackCore namespace BlackCore
@@ -58,7 +59,7 @@ namespace BlackCore
virtual bool isPaused() const = 0; virtual bool isPaused() const = 0;
//! Simulator running? //! Simulator running?
virtual bool isRunning() const = 0; virtual bool isSimulating() const = 0;
public slots: public slots:
@@ -75,8 +76,7 @@ namespace BlackCore
virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const = 0; virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const = 0;
//! Add new remote aircraft to the simulator //! Add new remote aircraft to the simulator
//! \todo Add parameter: aircraft model virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) = 0;
virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) = 0;
//! Add new aircraft situation //! Add new aircraft situation
virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation) = 0; virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation) = 0;
@@ -97,11 +97,14 @@ namespace BlackCore
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const = 0; virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const = 0;
//! Own aircraft Model //! Own aircraft Model
virtual BlackMisc::Network::CAircraftModel getAircraftModel() const = 0; virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const = 0;
//! Aircraft models for available remote aircraft //! Aircraft models for available remote aircrafts
virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const = 0; virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const = 0;
//! Remote aircraft in range having a valid model matching (which should be all aircraft in range)
virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const = 0;
//! Airports in range //! Airports in range
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const = 0; virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const = 0;
@@ -117,7 +120,7 @@ namespace BlackCore
void connectionStatusChanged(ISimulator::ConnectionStatus status); void connectionStatusChanged(ISimulator::ConnectionStatus status);
//! Emitted when own aircraft model has changed //! Emitted when own aircraft model has changed
void aircraftModelChanged(BlackMisc::Network::CAircraftModel model); void ownAircraftModelChanged(BlackMisc::Network::CAircraftModel model);
//! Simulator combined status //! Simulator combined status
void simulatorStatusChanged(bool connected, bool running, bool paused); void simulatorStatusChanged(bool connected, bool running, bool paused);
@@ -128,6 +131,8 @@ namespace BlackCore
//! Simulator stopped; //! Simulator stopped;
void simulatorStopped(); void simulatorStopped();
//! A single model has been matched
void modelMatchingCompleted(BlackMisc::Network::CAircraftModel model);
protected: protected:
//! Emit the combined status //! Emit the combined status

View File

@@ -21,6 +21,7 @@
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Aviation; using namespace BlackMisc::Aviation;
using namespace BlackMisc::Network;
using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Geo; using namespace BlackMisc::Geo;
using namespace BlackSim; using namespace BlackSim;
@@ -94,8 +95,10 @@ namespace BlackSimPlugin
return true; return true;
} }
void CSimulatorFs9::addRemoteAircraft(const CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) void CSimulatorFs9::addRemoteAircraft(const CAircraft &remoteAircraft, const CClient &remoteClient)
{ {
Q_UNUSED(remoteClient);
CCallsign callsign = remoteAircraft.getCallsign();
CFs9Client *client = new CFs9Client(this, callsign.toQString(), CTime(25, CTimeUnit::ms())); CFs9Client *client = new CFs9Client(this, callsign.toQString(), CTime(25, CTimeUnit::ms()));
client->setHostAddress(m_fs9Host->getHostAddress()); client->setHostAddress(m_fs9Host->getHostAddress());
client->setPlayerUserId(m_fs9Host->getPlayerUserId()); client->setPlayerUserId(m_fs9Host->getPlayerUserId());
@@ -103,7 +106,7 @@ namespace BlackSimPlugin
client->start(); client->start();
m_hashFs9Clients.insert(callsign, client); m_hashFs9Clients.insert(callsign, client);
addAircraftSituation(callsign, initialSituation); addAircraftSituation(callsign, remoteAircraft.getSituation());
} }
void CSimulatorFs9::addAircraftSituation(const CCallsign &callsign, const CAircraftSituation &situation) void CSimulatorFs9::addAircraftSituation(const CCallsign &callsign, const CAircraftSituation &situation)
@@ -259,7 +262,7 @@ namespace BlackSimPlugin
void CSimulatorFs9::ps_changeOwnAircraftModel(const QString &modelname) void CSimulatorFs9::ps_changeOwnAircraftModel(const QString &modelname)
{ {
m_aircraftModel.setQueriedModelString(modelname); m_aircraftModel.setQueriedModelString(modelname);
emit aircraftModelChanged(m_aircraftModel); emit ownAircraftModelChanged(m_aircraftModel);
} }
void CSimulatorFs9::ps_changeHostStatus(BlackSimPlugin::Fs9::CFs9Host::HostStatus status) void CSimulatorFs9::ps_changeHostStatus(BlackSimPlugin::Fs9::CFs9Host::HostStatus status)

View File

@@ -67,9 +67,8 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::isPaused //! \copydoc ISimulator::isPaused
virtual bool isPaused() const override { return m_simPaused; } virtual bool isPaused() const override { return m_simPaused; }
//! \copydoc ISimulator::isRunning //! \copydoc ISimulator::isSimulating
//! \todo RW fix, set better state here virtual bool isSimulating() const override { return isConnected(); }
virtual bool isRunning() const override { return true; }
//! Is time synchronization on? //! Is time synchronization on?
virtual bool isTimeSynchronized() const override { return m_syncTime; } virtual bool isTimeSynchronized() const override { return m_syncTime; }
@@ -89,7 +88,7 @@ namespace BlackSimPlugin
virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; } virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; }
//! \copydoc ISimulator::addRemoteAircraft() //! \copydoc ISimulator::addRemoteAircraft()
virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) override;
//! \copydoc ISimulator::addAircraftSituation() //! \copydoc ISimulator::addAircraftSituation()
virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override;
@@ -110,12 +109,14 @@ namespace BlackSimPlugin
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override; virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
//! \copydoc ISimulator::getAircraftModel() //! \copydoc ISimulator::getAircraftModel()
virtual BlackMisc::Network::CAircraftModel getAircraftModel() const override { return m_aircraftModel; } virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const override { return m_aircraftModel; }
//! \copydoc BlackCore::ISimulator::getInstalledModels //! \copydoc BlackCore::ISimulator::getInstalledModels
//! \todo
virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override { return {}; } virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override { return {}; }
//! \copydoc BlackCore::ISimulator::getCurrentlyMatchedModels
virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const override { return BlackMisc::Network::CAircraftModelList(); }
//! Airports in range //! Airports in range
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override; virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;

View File

@@ -1,7 +1,7 @@
include (../../../../config.pri) include (../../../../config.pri)
include (../../../../build.pri) include (../../../../build.pri)
QT += core dbus QT += core dbus xml
TARGET = simulator_fscommon TARGET = simulator_fscommon
TEMPLATE = lib TEMPLATE = lib

View File

@@ -1,7 +1,7 @@
include (../../../../config.pri) include (../../../../config.pri)
include (../../../../build.pri) include (../../../../build.pri)
QT += core dbus gui network concurrent QT += core dbus gui network concurrent xml
TARGET = simulator_fsx TARGET = simulator_fsx
TEMPLATE = lib TEMPLATE = lib

View File

@@ -10,12 +10,16 @@
#include "simulator_fsx.h" #include "simulator_fsx.h"
#include "simconnect_datadefinition.h" #include "simconnect_datadefinition.h"
#include "blacksim/fscommon/bcdconversions.h" #include "blacksim/fscommon/bcdconversions.h"
#include "blacksim/fscommon/vpilotmodelmappings.h"
#include "blacksim/fscommon/fscommonutil.h"
#include "blacksim/fsx/simconnectutilities.h" #include "blacksim/fsx/simconnectutilities.h"
#include "blacksim/fsx/fsxsimulatorsetup.h" #include "blacksim/fsx/fsxsimulatorsetup.h"
#include "blacksim/simulatorinfo.h" #include "blacksim/simulatorinfo.h"
#include "blackmisc/project.h" #include "blackmisc/project.h"
#include "blackmisc/avairportlist.h" #include "blackmisc/avairportlist.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/nwaircraftmodel.h"
#include "blackmisc/nwaircraftmappinglist.h"
#include <QTimer> #include <QTimer>
#include <QtConcurrent> #include <QtConcurrent>
@@ -41,6 +45,10 @@ namespace BlackSimPlugin
CFsxSimulatorSetup setup; CFsxSimulatorSetup setup;
setup.init(); // this fetches important settings on local side setup.init(); // this fetches important settings on local side
this->m_simulatorInfo.setSimulatorSetup(setup.getSettings()); this->m_simulatorInfo.setSimulatorSetup(setup.getSettings());
// hack to init mapper
CAircraftMapper *mapper = mapperInstance();
mapper->initCompletelyInBackground();
} }
CSimulatorFsx::~CSimulatorFsx() CSimulatorFsx::~CSimulatorFsx()
@@ -53,30 +61,27 @@ namespace BlackSimPlugin
return m_simConnected; return m_simConnected;
} }
bool CSimulatorFsx::isRunning() const bool CSimulatorFsx::isSimulating() const
{ {
return m_simRunning; return m_simRunning;
} }
bool CSimulatorFsx::isFsuipcConnected() const bool CSimulatorFsx::isFsuipcConnected() const
{ {
Q_ASSERT(m_fsuipc);
return m_fsuipc->isConnected(); return m_fsuipc->isConnected();
} }
bool CSimulatorFsx::connectTo() bool CSimulatorFsx::connectTo()
{ {
if (m_simConnected) { return true; } if (m_simConnected) { 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 connectionStatusChanged(ConnectionFailed); emit connectionStatusChanged(ConnectionFailed);
emitSimulatorCombinedStatus(); // all status values at once emitSimulatorCombinedStatus();
return false; return false;
} }
else else
{ {
Q_ASSERT(m_fsuipc);
this->m_fsuipc->connect(); // connect FSUIPC too this->m_fsuipc->connect(); // connect FSUIPC too
} }
@@ -96,7 +101,7 @@ namespace BlackSimPlugin
// simplified connect, timers and signals not in different thread // 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 this->m_fsuipc->connect(); // FSUIPC too
return true; return true;
}; };
@@ -134,27 +139,18 @@ namespace BlackSimPlugin
if (m_simConnected) { return true; } if (m_simConnected) { return true; }
HANDLE hSimConnect; // temporary handle HANDLE hSimConnect; // temporary handle
bool connect = false; bool connect = false;
if (FAILED(SimConnect_Open(&hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) connect = SUCCEEDED(SimConnect_Open(&hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0));
{
connect = false;
}
else
{
connect = true;
}
SimConnect_Close(hSimConnect); SimConnect_Close(hSimConnect);
return connect; return connect;
} }
void CSimulatorFsx::addRemoteAircraft(const CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) void CSimulatorFsx::addRemoteAircraft(const CAircraft &remoteAircraft, const CClient &remoteClient)
{ {
SIMCONNECT_DATA_INITPOSITION initialPosition; CCallsign callsign = remoteAircraft.getCallsign();
initialPosition.Latitude = initialSituation.latitude().value(CAngleUnit::deg()); Q_ASSERT(!callsign.isEmpty());
initialPosition.Longitude = initialSituation.longitude().value(CAngleUnit::deg()); if (callsign.isEmpty()) { return; }
initialPosition.Altitude = initialSituation.getAltitude().value(CLengthUnit::ft());
initialPosition.Pitch = initialSituation.getPitch().value(CAngleUnit::deg()); SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(remoteAircraft.getSituation());
initialPosition.Bank = initialSituation.getBank().value(CAngleUnit::deg());
initialPosition.Heading = initialSituation.getHeading().value(CAngleUnit::deg());
initialPosition.Airspeed = 0; initialPosition.Airspeed = 0;
initialPosition.OnGround = 0; initialPosition.OnGround = 0;
@@ -165,15 +161,28 @@ namespace BlackSimPlugin
m_simConnectObjects.insert(callsign, simObj); m_simConnectObjects.insert(callsign, simObj);
++m_nextObjID; ++m_nextObjID;
HRESULT hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, "Boeing 737-800 Paint1", qPrintable(callsign.toQString().left(12)), initialPosition, simObj.getRequestId()); addAircraftSituation(callsign, remoteAircraft.getSituation());
Q_UNUSED(hr);
addAircraftSituation(callsign, initialSituation); // matched models
CAircraftModel aircraftModel = modelMatching(remoteAircraft, remoteClient);
Q_ASSERT(remoteAircraft.getCallsign() == aircraftModel.getCallsign());
this->m_matchedModels.replaceOrAdd(&CAircraftModel::getCallsign, aircraftModel.getCallsign(), aircraftModel);
emit modelMatchingCompleted(aircraftModel);
// create AI
//! \todo isConnected() or isSimulating() ??
if (isConnected())
{
QByteArray m = aircraftModel.getModelString().toLocal8Bit();
HRESULT hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, m.constData(), qPrintable(callsign.toQString().left(12)), initialPosition, simObj.getRequestId());
if (hr != S_OK) { CLogMessage(this).error("SimConnect, can create AI traffic"); }
}
} }
void CSimulatorFsx::addAircraftSituation(const CCallsign &callsign, const CAircraftSituation &initialSituation) void CSimulatorFsx::addAircraftSituation(const CCallsign &callsign, const CAircraftSituation &initialSituation)
{ {
Q_ASSERT(m_simConnectObjects.contains(callsign)); // Q_ASSERT(m_simConnectObjects.contains(callsign));
if (!m_simConnectObjects.contains(callsign)) { return; }
CSimConnectObject simObj = m_simConnectObjects.value(callsign); CSimConnectObject simObj = m_simConnectObjects.value(callsign);
simObj.getInterpolator()->addAircraftSituation(initialSituation); simObj.getInterpolator()->addAircraftSituation(initialSituation);
@@ -190,12 +199,12 @@ namespace BlackSimPlugin
return this->m_simulatorInfo; return this->m_simulatorInfo;
} }
void CSimulatorFsx::setAircraftModel(const BlackMisc::Network::CAircraftModel &model) void CSimulatorFsx::setOwnAircraftModel(const BlackMisc::Network::CAircraftModel &model)
{ {
if (m_aircraftModel != model) if (m_ownAircraftModel != model)
{ {
m_aircraftModel = model; m_ownAircraftModel = model;
emit aircraftModelChanged(model); emit ownAircraftModelChanged(model);
} }
} }
@@ -269,7 +278,6 @@ namespace BlackSimPlugin
} }
changed = true; changed = true;
} }
if (changed) { this->m_ownAircraft.setTransponder(newTransponder); } if (changed) { this->m_ownAircraft.setTransponder(newTransponder); }
} }
@@ -312,6 +320,12 @@ namespace BlackSimPlugin
this->displayStatusMessage(message.asStatusMessage(true, true)); this->displayStatusMessage(message.asStatusMessage(true, true));
} }
CAircraftModelList CSimulatorFsx::getInstalledModels() const
{
if (!mapperInstance()) { return CAircraftModelList(); }
return mapperInstance()->getAircraftCfgEntriesList().toAircraftModelList();
}
CAirportList CSimulatorFsx::getAirportsInRange() const CAirportList CSimulatorFsx::getAirportsInRange() const
{ {
return this->m_airportsInRange; return this->m_airportsInRange;
@@ -327,10 +341,9 @@ namespace BlackSimPlugin
{ {
if (m_simRunning) { return; } if (m_simRunning) { return; }
m_simRunning = true; m_simRunning = true;
HRESULT hr; HRESULT hr = SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft,
hr = SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft, CSimConnectDefinitions::DataOwnAircraft,
CSimConnectDefinitions::DataOwnAircraft, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME);
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME);
hr += SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraftTitle, hr += SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraftTitle,
CSimConnectDefinitions::DataOwnAircraftTitle, CSimConnectDefinitions::DataOwnAircraftTitle,
@@ -364,15 +377,16 @@ namespace BlackSimPlugin
void CSimulatorFsx::onSimStopped() void CSimulatorFsx::onSimStopped()
{ {
if (!m_simRunning) return; if (!m_simRunning) { return; }
m_simRunning = false; m_simRunning = false;
mapperInstance()->gracefulShutdown(); // stop background reading if ongoing
emit simulatorStopped(); emit simulatorStopped();
emitSimulatorCombinedStatus(); emitSimulatorCombinedStatus(); // 3 states together
} }
void CSimulatorFsx::onSimFrame() void CSimulatorFsx::onSimFrame()
{ {
updateOtherAircrafts(); updateOtherAircraft();
} }
void CSimulatorFsx::onSimExit() void CSimulatorFsx::onSimExit()
@@ -397,8 +411,9 @@ namespace BlackSimPlugin
CComSystem com1 = m_ownAircraft.getCom1System(); // set defaults CComSystem com1 = m_ownAircraft.getCom1System(); // set defaults
CComSystem com2 = m_ownAircraft.getCom2System(); CComSystem com2 = m_ownAircraft.getCom2System();
CTransponder transponder = m_ownAircraft.getTransponder();
// When I change cockpit values in the SIM (from GUI to simulator, not originating from simulator) // When I change cockpit values in the sim (from GUI to simulator, not originating from simulator)
// it takes a little while before these values are set in the simulator. // it takes a little while before these values are set in the simulator.
// To avoid jitters, I wait some update cylces to stabilize the values // To avoid jitters, I wait some update cylces to stabilize the values
if (m_skipCockpitUpdateCycles < 1) if (m_skipCockpitUpdateCycles < 1)
@@ -411,8 +426,8 @@ namespace BlackSimPlugin
com2.setFrequencyStandby(CFrequency(simulatorOwnAircraft.com2StandbyMHz, CFrequencyUnit::MHz())); com2.setFrequencyStandby(CFrequency(simulatorOwnAircraft.com2StandbyMHz, CFrequencyUnit::MHz()));
m_ownAircraft.setCom2System(com2); m_ownAircraft.setCom2System(com2);
m_ownAircraft.setTransponderCode(simulatorOwnAircraft.transponderCode); transponder.setTransponderCode(simulatorOwnAircraft.transponderCode);
m_ownAircraft.setTransponder(transponder);
} }
else else
{ {
@@ -439,7 +454,7 @@ namespace BlackSimPlugin
[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; } if (it == m_simConnectObjects.end()) { return; }
// belongs to use // belongs to us
it->setObjectId(objectID); it->setObjectId(objectID);
SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID); SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID);
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeLat, 1, SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeLat, 1,
@@ -464,14 +479,15 @@ namespace BlackSimPlugin
void CSimulatorFsx::ps_dispatch() void CSimulatorFsx::ps_dispatch()
{ {
SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this); SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this);
this->m_fsuipc->process(); if (this->m_fsuipc) this->m_fsuipc->process();
} }
void CSimulatorFsx::ps_connectToFinished() void CSimulatorFsx::ps_connectToFinished()
{ {
if (m_watcherConnect.result()) if (m_watcherConnect.result())
{ {
initWhenConnected(); initEvents();
initDataDefinitionsWhenConnected();
m_simconnectTimerId = startTimer(50); m_simconnectTimerId = startTimer(50);
m_simConnected = true; m_simConnected = true;
@@ -492,6 +508,58 @@ namespace BlackSimPlugin
m_simConnectObjects.remove(simObject.getCallsign()); m_simConnectObjects.remove(simObject.getCallsign());
} }
HRESULT CSimulatorFsx::initEvents()
{
HRESULT hr = S_OK;
// System events, see http://msdn.microsoft.com/en-us/library/cc526983.aspx#SimConnect_SubscribeToSystemEvent
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventSimStatus, "Sim");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventObjectAdded, "ObjectAdded");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventObjectRemoved, "ObjectRemoved");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventFrame, "Frame");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventPause, "Pause");
if (hr != S_OK)
{
CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToSystemEvent failed";
return hr;
}
// Mapped events, see event ids here: http://msdn.microsoft.com/en-us/library/cc526980.aspx
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventPauseToggle, "PAUSE_TOGGLE");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, SystemEventSlewToggle, "SLEW_TOGGLE");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventFreezeLat, "FREEZE_LATITUDE_LONGITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventFreezeAlt, "FREEZE_ALTITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventFreezeAtt, "FREEZE_ATTITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom1Active, "COM_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom1Standby, "COM_STBY_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom2Active, "COM2_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom2Standby, "COM2_STBY_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTransponderCode, "XPNDR_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluYear, "ZULU_YEAR_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluDay, "ZULU_DAY_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluHours, "ZULU_HOURS_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluMinutes, "ZULU_MINUTES_SET");
if (hr != S_OK)
{
CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_MapClientEventToSimEvent failed";
return hr;
}
// facility
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, m_nextObjID++);
if (hr != S_OK)
{
CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToFacilities failed";
return hr;
}
return hr;
}
HRESULT CSimulatorFsx::initDataDefinitionsWhenConnected()
{
return CSimConnectDefinitions::initDataDefinitionsWhenConnected(m_hSimConnect);
}
HRESULT CSimulatorFsx::initWhenConnected() HRESULT CSimulatorFsx::initWhenConnected()
{ {
// called when connected // called when connected
@@ -514,81 +582,16 @@ namespace BlackSimPlugin
return hr; return hr;
} }
HRESULT CSimulatorFsx::initEvents() void CSimulatorFsx::updateOtherAircraft()
{
HRESULT hr = S_OK;
// System events, see http://msdn.microsoft.com/en-us/library/cc526983.aspx#SimConnect_SubscribeToSystemEvent
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventSimStatus, "Sim");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventObjectAdded, "ObjectAdded");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventObjectRemoved, "ObjectRemoved");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventFrame, "Frame");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventPause, "Pause");
if (hr != S_OK)
{
CLogMessage(this).error("FSX plugin: SimConnect_SubscribeToSystemEvent failed");
return hr;
}
// Mapped events, see event ids here: http://msdn.microsoft.com/en-us/library/cc526980.aspx
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventPauseToggle, "PAUSE_TOGGLE");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, SystemEventSlewToggle, "SLEW_TOGGLE");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventFreezeLat, "FREEZE_LATITUDE_LONGITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventFreezeAlt, "FREEZE_ALTITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventFreezeAtt, "FREEZE_ATTITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom1Active, "COM_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom1Standby, "COM_STBY_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom2Active, "COM2_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetCom2Standby, "COM2_STBY_RADIO_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTransponderCode, "XPNDR_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluYear, "ZULU_YEAR_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluDay, "ZULU_DAY_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluHours, "ZULU_HOURS_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluMinutes, "ZULU_MINUTES_SET");
if (hr != S_OK)
{
CLogMessage(this).error("FSX plugin: SimConnect_MapClientEventToSimEvent failed");
return hr;
}
// facility
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, m_nextObjID++);
if (hr != S_OK)
{
CLogMessage(this).error("FSX plugin: SimConnect_SubscribeToFacilities failed");
return hr;
}
return hr;
}
HRESULT CSimulatorFsx::initDataDefinitionsWhenConnected()
{
return CSimConnectDefinitions::initDataDefinitionsWhenConnected(m_hSimConnect);
}
void CSimulatorFsx::updateOtherAircrafts()
{ {
foreach(CSimConnectObject simObj, m_simConnectObjects) foreach(CSimConnectObject simObj, m_simConnectObjects)
{ {
if (simObj.getInterpolator()->hasEnoughAircraftSituations()) if (simObj.getInterpolator()->hasEnoughAircraftSituations())
{ {
SIMCONNECT_DATA_INITPOSITION position; SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(simObj.getInterpolator()->getCurrentSituation());
CAircraftSituation situation = simObj.getInterpolator()->getCurrentSituation();
position.Latitude = situation.latitude().value();
position.Longitude = situation.longitude().value();
position.Altitude = situation.getAltitude().value(CLengthUnit::ft());
position.Pitch = situation.getPitch().value();
position.Bank = situation.getBank().value();
position.Heading = situation.getHeading().value(CAngleUnit::deg());
position.Airspeed = situation.getGroundSpeed().value(CSpeedUnit::kts());
//! \todo : epic fail for helicopters and VTOPs!
position.OnGround = position.Airspeed < 30 ? 1 : 0;
DataDefinitionRemoteAircraftSituation ddAircraftSituation; DataDefinitionRemoteAircraftSituation ddAircraftSituation;
ddAircraftSituation.position = position; ddAircraftSituation.position = position;
//! \todo Gear handling with new protocol extension
DataDefinitionGearHandlePosition gearHandle; DataDefinitionGearHandlePosition gearHandle;
gearHandle.gearHandlePosition = position.Altitude < 1000 ? 1 : 0; gearHandle.gearHandlePosition = position.Altitude < 1000 ? 1 : 0;
@@ -603,6 +606,22 @@ namespace BlackSimPlugin
} }
} }
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxInitPosition(const CAircraftSituation &situation)
{
SIMCONNECT_DATA_INITPOSITION position;
position.Latitude = situation.latitude().value();
position.Longitude = situation.longitude().value();
position.Altitude = situation.getAltitude().value(CLengthUnit::ft());
position.Pitch = situation.getPitch().value();
position.Bank = situation.getBank().value();
position.Heading = situation.getHeading().value(CAngleUnit::deg());
position.Airspeed = situation.getGroundSpeed().value(CSpeedUnit::kts());
// TODO: epic fail for helicopters and VTOPs!
position.OnGround = position.Airspeed < 30 ? 1 : 0;
return position;
}
void CSimulatorFsx::synchronizeTime(const CTime &zuluTimeSim, const CTime &localTimeSim) void CSimulatorFsx::synchronizeTime(const CTime &zuluTimeSim, const CTime &localTimeSim)
{ {
if (!this->m_simTimeSynced) return; if (!this->m_simTimeSynced) return;
@@ -626,17 +645,101 @@ namespace BlackSimPlugin
int simMins = zuluTimeSim.valueRounded(CTimeUnit::min()); int simMins = zuluTimeSim.valueRounded(CTimeUnit::min());
int diffMins = qAbs(targetMins - simMins); int diffMins = qAbs(targetMins - simMins);
if (diffMins < 2) return; if (diffMins < 2) return;
HRESULT hr = S_OK; HRESULT hr = S_OK;
hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluHours, h, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluHours, h, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluMinutes, m, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluMinutes, m, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
if (hr != S_OK) if (hr != S_OK)
{ {
CLogMessage(this).warning("Sending time sync failed!"); CLogMessage(this).warning("Sending time sync failed!");
} }
else
{
m_syncDeferredCounter = 5; // allow some time to sync
CLogMessage(this).info("Synchronized time to UTC: %1") << myTime.toString();
}
}
m_syncDeferredCounter = 5; // allow some time to sync CAircraftMapper *CSimulatorFsx::mapperInstance()
CLogMessage(this).info("Synchronized time to UTC: %1") << myTime.toString(); {
static CAircraftMapper *mapper = new CAircraftMapper(
std::unique_ptr<CVPilotModelMappings>(new CVPilotModelMappings(true)), // currently hard wired
simObjectsDir()
);
return mapper;
}
CAircraftModel CSimulatorFsx::modelMatching(const CAircraft &remoteAircraft, const CClient &remoteClient)
{
CAircraftModel aircraftModel(remoteAircraft); // set defaults
// mapper ready?
if (!mapperInstance()->isInitialized())
{
//! \todo Model Matching before models are read
// will be removed later, just for experimental version
aircraftModel.setModelString("Boeing 737-800 Paint1");
aircraftModel.setDescription("Model mapper not ready");
return aircraftModel;
}
// Model by queried string
if (remoteClient.getAircraftModel().hasQueriedModelString())
{
QString directModelString = remoteClient.getAircraftModel().getModelString();
if (!directModelString.isEmpty() && mapperInstance()->containsModelWithTitle(directModelString))
{
aircraftModel = mapperInstance()->getModelWithTitle(directModelString);
aircraftModel.setModelType(CAircraftModel::TypeQueriedFromNetwork);
aircraftModel.setDescription("Direct query from network");
}
}
// ICAO to model
if (!aircraftModel.hasModelString())
{
CAircraftIcao icao = remoteAircraft.getIcaoInfo();
BlackMisc::Network::CAircraftMappingList mappingList = mapperInstance()->getAircraftMappingList().findByIcaoAircraftAndAirlineDesignator(icao, true);
if (!mappingList.isEmpty())
{
CAircraftModel modelFromMappings = mappingList.front().getModel();
// now turn the model from the mapping rules into a model from the simulator which has more metadata
aircraftModel = mapperInstance()->getModelWithTitle(modelFromMappings.getModelString());
Q_ASSERT(aircraftModel.getModelString() == modelFromMappings.getModelString());
aircraftModel.updateMissingParts(modelFromMappings); // update ICAO
aircraftModel.setModelType(CAircraftModel::TypeModelMatching);
}
}
// default or sanity check
if (!aircraftModel.hasModelString())
{
aircraftModel.setModelString("Boeing 737-800 Paint1");
aircraftModel.setDescription("Default model");
}
else
{
// check, do we have the model on disk
if (!mapperInstance()->containsModelWithTitle(aircraftModel.getModelString()))
{
const QString m = QString("Missing model: %1").arg(aircraftModel.getModelString());
Q_ASSERT_X(false, "modelMatching", m.toLocal8Bit().constData());
}
}
aircraftModel.setCallsign(remoteAircraft.getCallsign());
Q_ASSERT(!aircraftModel.getCallsign().isEmpty());
Q_ASSERT(aircraftModel.hasModelString());
return aircraftModel;
}
QString CSimulatorFsx::simObjectsDir()
{
//! \todo add FS9 dir
QString dir = CFsCommonUtil::fsxSimObjectsDirFromRegistry();
if (!dir.isEmpty()) { return dir; }
return "P:/FlightSimulatorX (MSI)/SimObjects";
// "p:/temp/SimObjects"
} }
} // namespace } // namespace
} // namespace } // namespace

View File

@@ -17,11 +17,13 @@
#include "../fscommon/fsuipc.h" #include "../fscommon/fsuipc.h"
#include "blackcore/simulator.h" #include "blackcore/simulator.h"
#include "blackcore/interpolator_linear.h" #include "blackcore/interpolator_linear.h"
#include "blacksim/simulatorinfo.h"
#include "blacksim/fscommon/aircraftmapper.h"
#include "blackmisc/avaircraft.h" #include "blackmisc/avaircraft.h"
#include "blackmisc/avairportlist.h" #include "blackmisc/avairportlist.h"
#include "blackmisc/statusmessage.h" #include "blackmisc/statusmessage.h"
#include "blackmisc/nwaircraftmodel.h" #include "blackmisc/nwaircraftmodel.h"
#include "blacksim/simulatorinfo.h" #include "blackmisc/nwclient.h"
#include <simconnect/SimConnect.h> #include <simconnect/SimConnect.h>
#include <QObject> #include <QObject>
@@ -38,26 +40,6 @@ namespace BlackSimPlugin
{ {
namespace Fsx namespace Fsx
{ {
//! Factory implementation to create CSimulatorFsx instances
class CSimulatorFsxFactory : public QObject, public BlackCore::ISimulatorFactory
{
Q_OBJECT
// TODO: @RW, move this string into CProject please
Q_PLUGIN_METADATA(IID "net.vatsim.PilotClient.BlackCore.SimulatorInterface")
Q_INTERFACES(BlackCore::ISimulatorFactory)
public:
//! \copydoc BlackCore::ISimulatorFactory::create()
virtual BlackCore::ISimulator *create(QObject *parent) override;
//! Simulator info
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
//! Log message category
static QString getMessageCategory() { return "swift.fsx.plugin"; }
};
//! SimConnect Event IDs //! SimConnect Event IDs
enum EventIds enum EventIds
{ {
@@ -80,7 +62,7 @@ namespace BlackSimPlugin
EventSetTimeZuluYear, EventSetTimeZuluYear,
EventSetTimeZuluDay, EventSetTimeZuluDay,
EventSetTimeZuluHours, EventSetTimeZuluHours,
EventSetTimeZuluMinutes, EventSetTimeZuluMinutes
}; };
//! FSX Simulator Implementation //! FSX Simulator Implementation
@@ -92,13 +74,14 @@ namespace BlackSimPlugin
//! Constructor //! Constructor
CSimulatorFsx(QObject *parent = nullptr); CSimulatorFsx(QObject *parent = nullptr);
//! Destructor
virtual ~CSimulatorFsx(); virtual ~CSimulatorFsx();
//! \copydoc ISimulator::isConnected() //! \copydoc ISimulator::isConnected()
virtual bool isConnected() const override; virtual bool isConnected() const override;
//! \copydoc ISimulator::isRunning //! \copydoc ISimulator::isSimulating
virtual bool isRunning() const override; virtual bool isSimulating() const override;
//! FSUIPC connected? //! FSUIPC connected?
bool isFsuipcConnected() const; bool isFsuipcConnected() const;
@@ -109,9 +92,6 @@ namespace BlackSimPlugin
//! SimConnect Callback //! SimConnect Callback
static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext); static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
//! Log message category
static QString getMessageCategory() { return "swift.fsx.plugin"; }
public slots: public slots:
//! \copydoc ISimulator::connectTo() //! \copydoc ISimulator::connectTo()
@@ -127,7 +107,7 @@ namespace BlackSimPlugin
virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; } virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; }
//! \copydoc ISimulator::addRemoteAircraft() //! \copydoc ISimulator::addRemoteAircraft()
virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) override;
//! \copydoc ISimulator::addAircraftSituation() //! \copydoc ISimulator::addAircraftSituation()
virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override;
@@ -148,11 +128,13 @@ namespace BlackSimPlugin
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override; virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
//! \copydoc ISimulator::getAircraftModel() //! \copydoc ISimulator::getAircraftModel()
virtual BlackMisc::Network::CAircraftModel getAircraftModel() const override { return m_aircraftModel; } virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const override { return m_ownAircraftModel; }
//! \copydoc BlackCore::ISimulator::getInstalledModels //! \copydoc BlackCore::ISimulator::getInstalledModels
//! \todo virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override;
virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override { return {}; }
//! \copydoc BlackCore::ISimulator::getCurrentlyMatchedModels
virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const override { return m_matchedModels; }
//! \copydoc ISimulator::getAirportsInRange //! \copydoc ISimulator::getAirportsInRange
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override; virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
@@ -181,21 +163,17 @@ namespace BlackSimPlugin
//! Called when data about our own aircraft are received //! Called when data about our own aircraft are received
void updateOwnAircraftFromSim(DataDefinitionOwnAircraft simulatorOwnAircraft); void updateOwnAircraftFromSim(DataDefinitionOwnAircraft simulatorOwnAircraft);
//! Called when data about SB area received //! Update from SB client area
void updateOwnAircraftFromSim(DataDefinitionClientAreaSb sbDataArea); void updateOwnAircraftFromSim(DataDefinitionClientAreaSb sbDataArea);
/*! //! Set ID of a SimConnect object
* Set ID of a SimConnect object
* \param requestID
* \param objectID
*/
void setSimConnectObjectID(DWORD requestID, DWORD objectID); void setSimConnectObjectID(DWORD requestID, DWORD objectID);
//! \private //! \private
void onSimExit(); void onSimExit();
//! \private //! \private
void setAircraftModel(const BlackMisc::Network::CAircraftModel &model); void setOwnAircraftModel(const BlackMisc::Network::CAircraftModel &model);
protected: protected:
//! Timer event //! Timer event
@@ -206,7 +184,7 @@ namespace BlackSimPlugin
//! Dispatch SimConnect messages //! Dispatch SimConnect messages
void ps_dispatch(); void ps_dispatch();
//! Called when asynchronous connection to SimConnect has finished //! Called when asynchronous connection to Simconnect has finished
void ps_connectToFinished(); void ps_connectToFinished();
private: private:
@@ -214,7 +192,7 @@ namespace BlackSimPlugin
//! Remove a remote aircraft //! Remove a remote aircraft
void removeRemoteAircraft(const CSimConnectObject &simObject); void removeRemoteAircraft(const CSimConnectObject &simObject);
//! Init SimConnect //! Init when connected
HRESULT initWhenConnected(); HRESULT initWhenConnected();
//! Initialize SimConnect system events //! Initialize SimConnect system events
@@ -224,34 +202,48 @@ namespace BlackSimPlugin
HRESULT initDataDefinitionsWhenConnected(); HRESULT initDataDefinitionsWhenConnected();
//! Update other aircrafts //! Update other aircrafts
void updateOtherAircrafts(); void updateOtherAircraft();
//! Format conversion
SIMCONNECT_DATA_INITPOSITION aircraftSituationToFsxInitPosition(const BlackMisc::Aviation::CAircraftSituation &situation);
//! Sync time with user's computer //! Sync time with user's computer
void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim); void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim);
static const int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again //! Get the mapper singleton
bool m_simConnected = false; //!< Is simulator connected? static BlackSim::FsCommon::CAircraftMapper *mapperInstance();
bool m_simRunning = false; //!< Simulator running?
bool m_simPaused = false; //!< Simulator paused?
bool m_simTimeSynced = false; //!< Time synchronized?
bool m_useSbOffsets = true; //!< SB offsets
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset;
HANDLE m_hSimConnect = nullptr; //!< Handle to SimConnect object
uint m_nextObjID = 1; //!< object ID TODO: also used as request id, where to we place other request ids as for facilities
QString simulatorDetails;
BlackSim::CSimulatorInfo m_simulatorInfo;
BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator
QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
BlackMisc::Network::CAircraftModel m_aircraftModel;
BlackMisc::Aviation::CAirportList m_airportsInRange;
int m_simconnectTimerId = -1; //! Experimental model matching
int m_skipCockpitUpdateCycles = 0; //!< Skip some update cycles to allow changes in simulator cockpit to be set static BlackMisc::Network::CAircraftModel modelMatching(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient);
//! SimObjects directory
static QString simObjectsDir();
static const int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again
bool m_simConnected = false; //!< Is simulator connected?
bool m_simRunning = false; //!< Simulator running?
bool m_simPaused = false; //!< Simulator paused?
bool m_simTimeSynced = false; //!< Time synchronized?
bool m_useSbOffsets = true; //!< with SB offsets
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
int m_simconnectTimerId = -1;
int m_skipCockpitUpdateCycles = 0; //!< Skip some update cycles to allow changes in simulator cockpit to be set
HANDLE m_hSimConnect = nullptr; //!< Handle to SimConnect object
uint m_nextObjID = 1; //!< object ID TODO: also used as request id, where to we place other request ids as for facilities
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset;
QString simulatorDetails; //!< describes version etc.
BlackSim::CSimulatorInfo m_simulatorInfo; //!< about the simulator
BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator
BlackMisc::Network::CAircraftModel m_ownAircraftModel; //!< own model
BlackMisc::Network::CAircraftModelList m_matchedModels; //!< mapped models
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< airports in range
QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
QFutureWatcher<bool> m_watcherConnect; QFutureWatcher<bool> m_watcherConnect;
QScopedPointer<FsCommon::CFsuipc> m_fsuipc; QScopedPointer<FsCommon::CFsuipc> m_fsuipc;
}; };
} // namespace }
} // namespace
} // namespace BlackCore
#endif // guard #endif // guard

View File

@@ -137,7 +137,7 @@ namespace BlackSimPlugin
DataDefinitionOwnAircraftModel *dataDefinitionModel = (DataDefinitionOwnAircraftModel *) &pObjData->dwData; DataDefinitionOwnAircraftModel *dataDefinitionModel = (DataDefinitionOwnAircraftModel *) &pObjData->dwData;
CAircraftModel model; CAircraftModel model;
model.setQueriedModelString(dataDefinitionModel->title); model.setQueriedModelString(dataDefinitionModel->title);
simulatorFsx->setAircraftModel(model); simulatorFsx->setOwnAircraftModel(model);
break; break;
} }
case CSimConnectDefinitions::RequestSimEnvironment: case CSimConnectDefinitions::RequestSimEnvironment:

View File

@@ -11,6 +11,8 @@
#include <QTimer> #include <QTimer>
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Aviation;
using namespace BlackMisc::Network;
namespace BlackSimPlugin namespace BlackSimPlugin
{ {
@@ -88,7 +90,7 @@ namespace BlackSimPlugin
if (m_service->isValid() && m_traffic->isValid() && m_traffic->initialize()) if (m_service->isValid() && m_traffic->isValid() && m_traffic->initialize())
{ {
// FIXME duplication // FIXME duplication
connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::ps_emitAircraftModelChanged); connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::ps_emitOwnAircraftModelChanged);
connect(m_service, &CXBusServiceProxy::airportsInRangeUpdated, this, &CSimulatorXPlane::ps_setAirportsInRange); connect(m_service, &CXBusServiceProxy::airportsInRangeUpdated, this, &CSimulatorXPlane::ps_setAirportsInRange);
m_service->updateAirportsInRange(); m_service->updateAirportsInRange();
m_watcher->setConnection(m_conn); m_watcher->setConnection(m_conn);
@@ -131,7 +133,7 @@ namespace BlackSimPlugin
delete m_service; delete m_service;
m_service = new CXBusServiceProxy(m_conn, this); m_service = new CXBusServiceProxy(m_conn, this);
// FIXME duplication // FIXME duplication
connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::ps_emitAircraftModelChanged); connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::ps_emitOwnAircraftModelChanged);
connect(m_service, &CXBusServiceProxy::airportsInRangeUpdated, this, &CSimulatorXPlane::ps_setAirportsInRange); connect(m_service, &CXBusServiceProxy::airportsInRangeUpdated, this, &CSimulatorXPlane::ps_setAirportsInRange);
m_service->updateAirportsInRange(); m_service->updateAirportsInRange();
} }
@@ -155,9 +157,9 @@ namespace BlackSimPlugin
emit connectionStatusChanged(ISimulator::Disconnected); emit connectionStatusChanged(ISimulator::Disconnected);
} }
void CSimulatorXPlane::ps_emitAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao) void CSimulatorXPlane::ps_emitOwnAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao)
{ {
emit aircraftModelChanged({ path, true }); emit ownAircraftModelChanged({ path, CAircraftModel::TypeOwnSimulatorModel });
Q_UNUSED(filename); Q_UNUSED(filename);
Q_UNUSED(livery); Q_UNUSED(livery);
Q_UNUSED(icao); Q_UNUSED(icao);
@@ -210,10 +212,10 @@ namespace BlackSimPlugin
Q_UNUSED(message); Q_UNUSED(message);
} }
BlackMisc::Network::CAircraftModel CSimulatorXPlane::getAircraftModel() const BlackMisc::Network::CAircraftModel CSimulatorXPlane::getOwnAircraftModel() const
{ {
if (! isConnected()) { return {}; } if (! isConnected()) { return {}; }
return { m_xplaneData.aircraftModelPath, true }; return { m_xplaneData.aircraftModelPath, CAircraftModel::TypeOwnSimulatorModel };
} }
BlackMisc::Network::CAircraftModelList CSimulatorXPlane::getInstalledModels() const BlackMisc::Network::CAircraftModelList CSimulatorXPlane::getInstalledModels() const
@@ -286,11 +288,15 @@ namespace BlackSimPlugin
return false; return false;
} }
void CSimulatorXPlane::addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situ) void CSimulatorXPlane::addRemoteAircraft(const Aviation::CAircraft &remoteAircraft, const Network::CClient &remoteClient)
{ {
Q_UNUSED(remoteClient);
if (! isConnected()) { return; } if (! isConnected()) { return; }
m_traffic->addPlane(callsign.asString(), "A320", "YYY", "YYY"); // KB: from what I can see here all data are available
addAircraftSituation(callsign, situ); // Is there any model matching required ????
CAircraftIcao icao = remoteAircraft.getIcaoInfo();
m_traffic->addPlane(remoteAircraft.getCallsign().asString(), icao.getAircraftDesignator(), icao.getAirlineDesignator(), icao.getLivery());
addAircraftSituation(remoteAircraft.getCallsign(), remoteAircraft.getSituation());
} }
void CSimulatorXPlane::addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, void CSimulatorXPlane::addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign,

View File

@@ -44,8 +44,8 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::isSimPaused //! \copydoc ISimulator::isSimPaused
virtual bool isPaused() const override { return false; } virtual bool isPaused() const override { return false; }
//! \copydoc ISimulator::isRunning //! \copydoc ISimulator::isSimulating
virtual bool isRunning() const override { return isConnected(); } virtual bool isSimulating() const override { return isConnected(); }
public slots: public slots:
//! \copydoc BlackCore::ISimulator::connectTo //! \copydoc BlackCore::ISimulator::connectTo
@@ -60,13 +60,12 @@ namespace BlackSimPlugin
//! \copydoc BlackCore::ISimulator::getOwnAircraft //! \copydoc BlackCore::ISimulator::getOwnAircraft
virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override; virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override;
//! \copydoc BlackCore::ISimulator::addRemoteAircraft //! \copydoc ISimulator::addRemoteAircraft()
virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) override;
const BlackMisc::Aviation::CAircraftSituation &initialSituation) override;
//! \copydoc BlackCore::ISimulator::addAircraftSituation //! \copydoc BlackCore::ISimulator::addAircraftSituation
virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign,
const BlackMisc::Aviation::CAircraftSituation &situation) override; const BlackMisc::Aviation::CAircraftSituation &situation) override;
//! \copydoc BlackCore::ISimulator::removeRemoteAircraft //! \copydoc BlackCore::ISimulator::removeRemoteAircraft
virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
@@ -84,11 +83,14 @@ namespace BlackSimPlugin
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override; virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
//! \copydoc BlackCore::ISimulator::getAircraftModel //! \copydoc BlackCore::ISimulator::getAircraftModel
virtual BlackMisc::Network::CAircraftModel getAircraftModel() const override; virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const override;
//! \copydoc BlackCore::ISimulator::getInstalledModels //! \copydoc BlackCore::ISimulator::getInstalledModels
virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override; virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override;
//! \copydoc BlackCore::ISimulator::getCurrentlyMatchedModels
virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const override { return BlackMisc::Network::CAircraftModelList(); }
//! Airports in range //! Airports in range
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override; virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
@@ -102,7 +104,7 @@ namespace BlackSimPlugin
void ps_serviceRegistered(const QString &serviceName); void ps_serviceRegistered(const QString &serviceName);
void ps_serviceUnregistered(); void ps_serviceUnregistered();
void ps_setAirportsInRange(const QStringList &icaoCodes, const QStringList &names, const BlackMisc::CSequence<double> &lats, const BlackMisc::CSequence<double> &lons, const BlackMisc::CSequence<double> &alts); void ps_setAirportsInRange(const QStringList &icaoCodes, const QStringList &names, const BlackMisc::CSequence<double> &lats, const BlackMisc::CSequence<double> &lons, const BlackMisc::CSequence<double> &alts);
void ps_emitAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao); void ps_emitOwnAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao);
void ps_fastTimerTimeout(); void ps_fastTimerTimeout();
void ps_slowTimerTimeout(); void ps_slowTimerTimeout();
@@ -141,7 +143,7 @@ namespace BlackSimPlugin
m_xplaneData = { "", "", 0, 0, 0, 0, 0, 0, 0, 122800, 122800, 122800, 122800, 2000, 0, false }; m_xplaneData = { "", "", 0, 0, 0, 0, 0, 0, 0, 122800, 122800, 122800, 122800, 2000, 0, false };
} }
}; };
//! Factory for creating CSimulatorXPlane instance //! Factory for creating CSimulatorXPlane instance
class CSimulatorXPlaneFactory : public QObject, public BlackCore::ISimulatorFactory class CSimulatorXPlaneFactory : public QObject, public BlackCore::ISimulatorFactory
{ {