mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-01 05:26:45 +08:00
refs #369, adjusted plugins
* common base class for FS drivers * moved mapper into common base class * reflect changes for own aircraft provider ** removed member functions ** removed unused members
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKSIMPLUGIN_FS9_FS9SDK_H
|
||||
#define BLACKSIMPLUGIN_FS9_FS9SDK_H
|
||||
|
||||
@@ -19,8 +21,6 @@
|
||||
#endif
|
||||
#include <dplay8.h>
|
||||
|
||||
//! \file
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fs9
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
include (../../../../config.pri)
|
||||
include (../../../../build.pri)
|
||||
|
||||
QT += core dbus gui network
|
||||
QT += core dbus gui network concurrent xml
|
||||
|
||||
TARGET = simulator_fs9
|
||||
TEMPLATE = lib
|
||||
|
||||
@@ -28,15 +28,17 @@ using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Geo;
|
||||
using namespace BlackSim;
|
||||
using namespace BlackSimPlugin::Fs9;
|
||||
using namespace BlackSimPlugin::FsCommon;
|
||||
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fs9
|
||||
{
|
||||
BlackCore::ISimulator *CSimulatorFs9Factory::create(QObject *parent)
|
||||
BlackCore::ISimulator *CSimulatorFs9Factory::create(IOwnAircraftProvider *ownAircraft, QObject *parent)
|
||||
{
|
||||
registerMetadata();
|
||||
return new Fs9::CSimulatorFs9(parent);
|
||||
return new Fs9::CSimulatorFs9(ownAircraft, parent);
|
||||
}
|
||||
|
||||
BlackSim::CSimulatorInfo CSimulatorFs9Factory::getSimulatorInfo() const
|
||||
@@ -44,12 +46,10 @@ namespace BlackSimPlugin
|
||||
return CSimulatorInfo::FS9();
|
||||
}
|
||||
|
||||
CSimulatorFs9::CSimulatorFs9(QObject *parent) :
|
||||
ISimulator(parent),
|
||||
CSimulatorFs9::CSimulatorFs9(IOwnAircraftProvider *ownAircraft, QObject *parent) :
|
||||
CSimulatorFsCommon(CSimulatorInfo::FS9(), ownAircraft, parent),
|
||||
m_fs9Host(new CFs9Host(this)),
|
||||
m_lobbyClient(new CLobbyClient(this)),
|
||||
m_simulatorInfo(CSimulatorInfo::FS9()),
|
||||
m_fsuipc(new FsCommon::CFsuipc())
|
||||
m_lobbyClient(new CLobbyClient(this))
|
||||
{
|
||||
connect(m_fs9Host.data(), &CFs9Host::customPacketReceived, this, &CSimulatorFs9::ps_processFs9Message);
|
||||
connect(m_fs9Host.data(), &CFs9Host::statusChanged, this, &CSimulatorFs9::ps_changeHostStatus);
|
||||
@@ -68,13 +68,19 @@ namespace BlackSimPlugin
|
||||
|
||||
bool CSimulatorFs9::connectTo()
|
||||
{
|
||||
Q_ASSERT(m_fsuipc);
|
||||
m_fsuipc->connect(); // connect FSUIPC too
|
||||
|
||||
// If we are already hosting, connect FS0 through lobby connection
|
||||
if (m_isHosting) m_lobbyClient->connectFs9ToHost(m_fs9Host->getHostAddress());
|
||||
if (m_isHosting)
|
||||
{
|
||||
m_lobbyClient->connectFs9ToHost(m_fs9Host->getHostAddress());
|
||||
}
|
||||
// If not, deferre connection until host is setup
|
||||
else m_startedLobbyConnection = true;
|
||||
|
||||
else
|
||||
{
|
||||
m_startedLobbyConnection = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,10 +96,8 @@ namespace BlackSimPlugin
|
||||
|
||||
emit connectionStatusChanged(ISimulator::Disconnected);
|
||||
if (m_fs9Host) { m_fs9Host->quit(); }
|
||||
m_fsuipc->disconnect();
|
||||
|
||||
CSimulatorFsCommon::disconnectFrom();
|
||||
m_isHosting = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -137,62 +141,55 @@ namespace BlackSimPlugin
|
||||
//! \todo really update aircraft in SIM
|
||||
}
|
||||
|
||||
bool CSimulatorFs9::updateOwnSimulatorCockpit(const CAircraft &ownAircraft)
|
||||
bool CSimulatorFs9::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
|
||||
{
|
||||
if (originator == this->simulatorOriginator()) { return false; }
|
||||
if (!this->isSimulating()) { return false; }
|
||||
|
||||
// actually those data should be the same as ownAircraft
|
||||
CComSystem newCom1 = ownAircraft.getCom1System();
|
||||
CComSystem newCom2 = ownAircraft.getCom2System();
|
||||
CTransponder newTransponder = ownAircraft.getTransponder();
|
||||
|
||||
bool changed = false;
|
||||
if (newCom1 != this->m_ownAircraft.getCom1System())
|
||||
if (newCom1.getFrequencyActive() != this->m_simCom1.getFrequencyActive())
|
||||
{
|
||||
if (newCom1.getFrequencyActive() != this->m_ownAircraft.getCom1System().getFrequencyActive())
|
||||
{
|
||||
// CFrequency newFreq = newCom1.getFrequencyActive();
|
||||
changed = true;
|
||||
|
||||
}
|
||||
if (newCom1.getFrequencyStandby() != this->m_ownAircraft.getCom1System().getFrequencyStandby())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
this->m_ownAircraft.setCom1System(newCom1);
|
||||
}
|
||||
if (newCom1.getFrequencyStandby() != this->m_simCom1.getFrequencyStandby())
|
||||
{
|
||||
// CFrequency newFreq = newCom1.getFrequencyStandby();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (newCom2 != this->m_ownAircraft.getCom2System())
|
||||
if (newCom2.getFrequencyActive() != this->m_simCom2.getFrequencyActive())
|
||||
{
|
||||
if (newCom2.getFrequencyActive() != this->m_ownAircraft.getCom2System().getFrequencyActive())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (newCom2.getFrequencyStandby() != this->m_ownAircraft.getCom2System().getFrequencyStandby())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
this->m_ownAircraft.setCom2System(newCom2);
|
||||
// CFrequency newFreq = newCom2.getFrequencyActive();
|
||||
changed = true;
|
||||
}
|
||||
if (newCom2.getFrequencyStandby() != this->m_simCom2.getFrequencyStandby())
|
||||
{
|
||||
// CFrequency newFreq = newCom2.getFrequencyStandby();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (newTransponder != this->m_ownAircraft.getTransponder())
|
||||
if (newTransponder.getTransponderCode() != this->m_simTransponder.getTransponderCode())
|
||||
{
|
||||
if (newTransponder.getTransponderCode() != this->m_ownAircraft.getTransponder().getTransponderCode())
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
this->m_ownAircraft.setTransponder(newTransponder);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (newTransponder.getTransponderMode() != this->m_simTransponder.getTransponderMode())
|
||||
{
|
||||
}
|
||||
|
||||
// avoid changes of cockpit back to old values due to an outdated read back value
|
||||
|
||||
// bye
|
||||
return changed;
|
||||
}
|
||||
|
||||
CSimulatorInfo CSimulatorFs9::getSimulatorInfo() const
|
||||
{
|
||||
return this->m_simulatorInfo;
|
||||
}
|
||||
|
||||
void CSimulatorFs9::displayStatusMessage(const BlackMisc::CStatusMessage &message) const
|
||||
{
|
||||
if (message.getSeverity() != BlackMisc::CStatusMessage::SeverityDebug)
|
||||
@@ -207,23 +204,6 @@ namespace BlackSimPlugin
|
||||
this->displayStatusMessage(message.asStatusMessage(true, true));
|
||||
}
|
||||
|
||||
CAirportList CSimulatorFs9::getAirportsInRange() const
|
||||
{
|
||||
return this->m_airportsInRange;
|
||||
}
|
||||
|
||||
void CSimulatorFs9::setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset)
|
||||
{
|
||||
this->m_syncTime = enable;
|
||||
this->m_syncTimeOffset = offset;
|
||||
}
|
||||
|
||||
CPixmap CSimulatorFs9::iconForModel(const QString &modelString) const
|
||||
{
|
||||
Q_UNUSED(modelString);
|
||||
return CPixmap();
|
||||
}
|
||||
|
||||
void CSimulatorFs9::timerEvent(QTimerEvent * /* event */)
|
||||
{
|
||||
ps_dispatch();
|
||||
@@ -231,14 +211,20 @@ namespace BlackSimPlugin
|
||||
|
||||
void CSimulatorFs9::ps_dispatch()
|
||||
{
|
||||
if (m_fsuipc) m_fsuipc->process();
|
||||
updateOwnAircraftFromSim(m_fsuipc->getOwnAircraft());
|
||||
if (m_fsuipc)
|
||||
{
|
||||
CSimulatedAircraft fsuipcAircraft(ownAircraft());
|
||||
bool ok = m_fsuipc->read(fsuipcAircraft);
|
||||
if (ok)
|
||||
{
|
||||
updateOwnAircraftFromSimulator(fsuipcAircraft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorFs9::ps_processFs9Message(const QByteArray &message)
|
||||
{
|
||||
CFs9Sdk::MULTIPLAYER_PACKET_ID messageType = MultiPlayerPacketParser::readType(message);
|
||||
|
||||
switch (messageType)
|
||||
{
|
||||
case CFs9Sdk::MULTIPLAYER_PACKET_ID_PARAMS:
|
||||
@@ -249,14 +235,14 @@ namespace BlackSimPlugin
|
||||
{
|
||||
MPChangePlayerPlane mpChangePlayerPlane;
|
||||
MultiPlayerPacketParser::readMessage(message, mpChangePlayerPlane);
|
||||
ps_changeOwnAircraftModel(mpChangePlayerPlane.aircraft_name);
|
||||
setOwnAircraftModel(mpChangePlayerPlane.aircraft_name);
|
||||
break;
|
||||
}
|
||||
case CFs9Sdk::MULTIPLAYER_PACKET_ID_POSITION_VELOCITY:
|
||||
{
|
||||
MPPositionVelocity mpPositionVelocity;
|
||||
MultiPlayerPacketParser::readMessage(message, mpPositionVelocity);
|
||||
m_ownAircraft.setSituation(aircraftSituationfromFS9(mpPositionVelocity));
|
||||
ownAircraft().setSituation(aircraftSituationfromFS9(mpPositionVelocity));
|
||||
break;
|
||||
}
|
||||
case CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND:
|
||||
@@ -271,14 +257,6 @@ namespace BlackSimPlugin
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorFs9::ps_changeOwnAircraftModel(const QString &modelname)
|
||||
{
|
||||
CAircraftModel model = m_ownAircraft.getModel();
|
||||
model.setModelString(modelname);
|
||||
m_ownAircraft.setModel(model);
|
||||
emit ownAircraftModelChanged(m_ownAircraft);
|
||||
}
|
||||
|
||||
void CSimulatorFs9::ps_changeHostStatus(BlackSimPlugin::Fs9::CFs9Host::HostStatus status)
|
||||
{
|
||||
switch (status)
|
||||
@@ -306,11 +284,13 @@ namespace BlackSimPlugin
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorFs9::updateOwnAircraftFromSim(const CAircraft &ownAircraft)
|
||||
void CSimulatorFs9::updateOwnAircraftFromSimulator(const CAircraft &simDataOwnAircraft)
|
||||
{
|
||||
m_ownAircraft.setCom1System(ownAircraft.getCom1System());
|
||||
m_ownAircraft.setCom2System(ownAircraft.getCom2System());
|
||||
m_ownAircraft.setTransponder(ownAircraft.getTransponder());
|
||||
this->providerUpdateCockpit(
|
||||
simDataOwnAircraft.getCom1System(),
|
||||
simDataOwnAircraft.getCom2System(),
|
||||
simDataOwnAircraft.getTransponder(),
|
||||
this->simulatorOriginator());
|
||||
}
|
||||
|
||||
void CSimulatorFs9::disconnectAllClients()
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKSIMPLUGIN_SIMULATOR_FS9_H
|
||||
#define BLACKSIMPLUGIN_SIMULATOR_FS9_H
|
||||
|
||||
#include "fs9_host.h"
|
||||
#include "fs9_client.h"
|
||||
#include "lobby_client.h"
|
||||
#include "../fscommon/fsuipc.h"
|
||||
#include "../fscommon/simulator_fscommon.h"
|
||||
#include "blackcore/simulator.h"
|
||||
#include "blackcore/interpolator_linear.h"
|
||||
#include "blackmisc/simulation/aircraftmodel.h"
|
||||
@@ -26,8 +28,6 @@
|
||||
#include <QThread>
|
||||
#include <QHash>
|
||||
|
||||
//! \file
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fs9
|
||||
@@ -41,20 +41,20 @@ namespace BlackSimPlugin
|
||||
|
||||
public:
|
||||
//! \copydoc BlackCore::ISimulatorFactory::create()
|
||||
virtual BlackCore::ISimulator *create(QObject *parent) override;
|
||||
virtual BlackCore::ISimulator *create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent) override;
|
||||
|
||||
//! Simulator info
|
||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
|
||||
};
|
||||
|
||||
//! FSX Simulator Implementation
|
||||
class CSimulatorFs9 : public BlackCore::ISimulator
|
||||
class CSimulatorFs9 : public BlackSimPlugin::FsCommon::CSimulatorFsCommon
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
CSimulatorFs9(QObject *parent = nullptr);
|
||||
CSimulatorFs9(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CSimulatorFs9();
|
||||
@@ -65,15 +65,9 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::canConnect()
|
||||
virtual bool canConnect() const override { return true; }
|
||||
|
||||
//! \copydoc ISimulator::isPaused
|
||||
virtual bool isPaused() const override { return m_simPaused; }
|
||||
|
||||
//! \copydoc ISimulator::isSimulating
|
||||
virtual bool isSimulating() const override { return isConnected(); }
|
||||
|
||||
//! Is time synchronization on?
|
||||
virtual bool isTimeSynchronized() const override { return m_syncTime; }
|
||||
|
||||
public slots:
|
||||
|
||||
//! \copydoc ISimulator::connectTo()
|
||||
@@ -85,9 +79,6 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::disconnectFrom()
|
||||
virtual bool disconnectFrom() override;
|
||||
|
||||
//! \copydoc ISimulator::getOwnAircraft()
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const override { return m_ownAircraft; }
|
||||
|
||||
//! \copydoc ISimulator::addRemoteAircraft()
|
||||
virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
|
||||
|
||||
@@ -104,10 +95,7 @@ namespace BlackSimPlugin
|
||||
virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override;
|
||||
|
||||
//! \copydoc ISimulator::updateOwnSimulatorCockpit()
|
||||
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft) override;
|
||||
|
||||
//! \copydoc ISimulator::getSimulatorInfo()
|
||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
|
||||
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft, const QString &originator) override;
|
||||
|
||||
//! \copydoc ISimulator::displayStatusMessage()
|
||||
virtual void displayStatusMessage(const BlackMisc::CStatusMessage &message) const override;
|
||||
@@ -115,25 +103,6 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::displayTextMessage()
|
||||
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
|
||||
|
||||
//! \copydoc ISimulator::getAircraftModel()
|
||||
virtual BlackMisc::Simulation::CAircraftModel getOwnAircraftModel() const override { return m_ownAircraft.getModel(); }
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getInstalledModels
|
||||
virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override { return {}; }
|
||||
|
||||
//! Airports in range
|
||||
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
|
||||
|
||||
//! Set time synchronization between simulator and user's computer time
|
||||
//! \remarks not all drivers implement this, e.g. if it is an intrinsic simulator feature
|
||||
virtual void setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset) override;
|
||||
|
||||
//! Time synchronization offset
|
||||
virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override { return m_syncTimeOffset; }
|
||||
|
||||
//! \copydoc ISimulator::iconForModel
|
||||
virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override;
|
||||
|
||||
protected:
|
||||
//! Timer event
|
||||
virtual void timerEvent(QTimerEvent *event);
|
||||
@@ -146,38 +115,22 @@ namespace BlackSimPlugin
|
||||
//! Process incoming FS9 message
|
||||
void ps_processFs9Message(const QByteArray &message);
|
||||
|
||||
//! Change own aircraft model string
|
||||
void ps_changeOwnAircraftModel(const QString &modelname);
|
||||
|
||||
//! Change DirectPlay host status
|
||||
void ps_changeHostStatus(BlackSimPlugin::Fs9::CFs9Host::HostStatus status);
|
||||
|
||||
private:
|
||||
|
||||
//! Called when data about our own aircraft are received
|
||||
void updateOwnAircraftFromSim(const BlackMisc::Aviation::CAircraft &ownAircraft);
|
||||
void updateOwnAircraftFromSimulator(const BlackMisc::Aviation::CAircraft &ownAircraft);
|
||||
|
||||
void disconnectAllClients();
|
||||
|
||||
// DirectPlay object handling
|
||||
QPointer<CFs9Host> m_fs9Host;
|
||||
bool m_isHosting = false; //!< Is sim connected
|
||||
bool m_startedLobbyConnection = false;
|
||||
bool m_syncTime = false; //!< Time synchronized?
|
||||
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
|
||||
bool m_simPaused = false; //!< Simulator paused?
|
||||
|
||||
bool m_isHosting = false; //!< Is sim connected
|
||||
bool m_startedLobbyConnection = false;
|
||||
QHash<BlackMisc::Aviation::CCallsign, QPointer<CFs9Client>> m_hashFs9Clients;
|
||||
|
||||
CLobbyClient *m_lobbyClient;
|
||||
|
||||
BlackSim::CSimulatorInfo m_simulatorInfo;
|
||||
BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator
|
||||
BlackMisc::Aviation::CAirportList m_airportsInRange;
|
||||
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset;
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft;
|
||||
|
||||
QScopedPointer<FsCommon::CFsuipc> m_fsuipc;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
include (../../../../config.pri)
|
||||
include (../../../../build.pri)
|
||||
|
||||
QT += core dbus xml
|
||||
QT += core dbus concurrent xml
|
||||
|
||||
TARGET = simulator_fscommon
|
||||
TEMPLATE = lib
|
||||
|
||||
247
src/plugins/simulator/fscommon/simulator_fscommon.cpp
Normal file
247
src/plugins/simulator/fscommon/simulator_fscommon.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift Project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "simulator_fscommon.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
#include "blacksim/fscommon/vpilotmodelmappings.h"
|
||||
#include "blacksim/fscommon/fscommonutil.h"
|
||||
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Simulation;
|
||||
using namespace BlackSim::FsCommon;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackSimPlugin::FsCommon;
|
||||
using namespace BlackSim;
|
||||
using namespace BlackSim::FsCommon;
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace FsCommon
|
||||
{
|
||||
|
||||
CSimulatorFsCommon::CSimulatorFsCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent) :
|
||||
ISimulator(parent), COwnAircraftProviderSupport(ownAircraft), m_simulatorInfo(simInfo), m_fsuipc(new FsCommon::CFsuipc())
|
||||
{
|
||||
// hack to init mapper
|
||||
CAircraftMapper *mapper = mapperInstance();
|
||||
connect(mapper, &CAircraftMapper::initCompleted, this, &CSimulatorFsCommon::ps_mapperInitialized);
|
||||
mapper->initCompletelyInBackground();
|
||||
}
|
||||
|
||||
CSimulatorFsCommon::~CSimulatorFsCommon()
|
||||
{ }
|
||||
|
||||
void CSimulatorFsCommon::ps_mapperInitialized(bool success)
|
||||
{
|
||||
if (success) { emit this->installedAircraftModelsChanged(); }
|
||||
}
|
||||
|
||||
bool CSimulatorFsCommon::disconnectFrom()
|
||||
{
|
||||
if (this->m_fsuipc) { this->m_fsuipc->disconnect(); }
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSimulatorFsCommon::isFsuipcConnected() const
|
||||
{
|
||||
return !m_fsuipc.isNull() && m_fsuipc->isConnected();
|
||||
}
|
||||
|
||||
CTime CSimulatorFsCommon::getTimeSynchronizationOffset() const
|
||||
{
|
||||
return m_syncTimeOffset;
|
||||
}
|
||||
|
||||
void CSimulatorFsCommon::setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset)
|
||||
{
|
||||
this->m_simTimeSynced = enable;
|
||||
this->m_syncTimeOffset = offset;
|
||||
}
|
||||
|
||||
BlackSim::CSimulatorInfo CSimulatorFsCommon::getSimulatorInfo() const
|
||||
{
|
||||
return this->m_simulatorInfo;
|
||||
}
|
||||
|
||||
CSimulatedAircraftList CSimulatorFsCommon::getRemoteAircraft() const
|
||||
{
|
||||
return this->m_remoteAircraft;
|
||||
}
|
||||
|
||||
CAirportList CSimulatorFsCommon::getAirportsInRange() const
|
||||
{
|
||||
return this->m_airportsInRange;
|
||||
}
|
||||
|
||||
|
||||
void CSimulatorFsCommon::setOwnAircraftModel(const QString &modelName)
|
||||
{
|
||||
CAircraftModel model = ownAircraft().getModel();
|
||||
model.setModelString(modelName);
|
||||
this->setOwnAircraftModel(model);
|
||||
}
|
||||
|
||||
void CSimulatorFsCommon::setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model)
|
||||
{
|
||||
if (ownAircraft().getModel() != model)
|
||||
{
|
||||
CAircraftModel newModel(model);
|
||||
newModel.setModelType(CAircraftModel::TypeOwnSimulatorModel);
|
||||
if (this->mapperInstance() && this->mapperInstance()->isInitialized())
|
||||
{
|
||||
// reverse lookup of ICAO
|
||||
CAircraftMappingList ml = this->mapperInstance()->getAircraftMappingList().findByModelString(model.getModelString());
|
||||
if (!ml.isEmpty())
|
||||
{
|
||||
CAircraftMapping mapping = ml.front();
|
||||
newModel.setIcao(mapping.getIcao());
|
||||
}
|
||||
}
|
||||
ownAircraft().setModel(newModel);
|
||||
emit ownAircraftModelChanged(ownAircraft());
|
||||
}
|
||||
}
|
||||
|
||||
CAircraftMapper *CSimulatorFsCommon::mapperInstance()
|
||||
{
|
||||
static CAircraftMapper *mapper = new CAircraftMapper(
|
||||
std::unique_ptr<CVPilotModelMappings>(new CVPilotModelMappings(true)), // currently hard wired
|
||||
simObjectsDir()
|
||||
);
|
||||
return mapper;
|
||||
}
|
||||
|
||||
CAircraftModel CSimulatorFsCommon::modelMatching(const CSimulatedAircraft &remoteAircraft)
|
||||
{
|
||||
|
||||
// Manually set string?
|
||||
if (remoteAircraft.getModel().hasManuallySetString())
|
||||
{
|
||||
// manual set model
|
||||
return remoteAircraft.getModel();
|
||||
}
|
||||
|
||||
// default model
|
||||
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");
|
||||
CLogMessage(static_cast<CSimulatorFsCommon *>(nullptr)).warning("Mapper not ready, set to default model");
|
||||
return aircraftModel;
|
||||
}
|
||||
|
||||
// Model by queried string
|
||||
const CClient remoteClient = remoteAircraft.getClient();
|
||||
if (remoteClient.getAircraftModel().hasQueriedModelString())
|
||||
{
|
||||
QString directModelString = remoteClient.getAircraftModel().getModelString();
|
||||
if (!directModelString.isEmpty() && mapperInstance()->containsModelWithTitle(directModelString))
|
||||
{
|
||||
aircraftModel = mapperInstance()->getModelWithTitle(directModelString);
|
||||
aircraftModel.setModelType(CAircraftModel::TypeQueriedFromNetwork);
|
||||
}
|
||||
}
|
||||
|
||||
// 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");
|
||||
aircraftModel.setModelType(CAircraftModel::TypeModelMatching);
|
||||
}
|
||||
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());
|
||||
Q_ASSERT(aircraftModel.getModelType() != CAircraftModel::TypeUnknown);
|
||||
return aircraftModel;
|
||||
}
|
||||
|
||||
QString CSimulatorFsCommon::simObjectsDir()
|
||||
{
|
||||
//! \todo add FS9 dir
|
||||
QString dir = CFsCommonUtil::fsxSimObjectsDirFromRegistry();
|
||||
if (!dir.isEmpty()) { return dir; }
|
||||
return "P:/FlightSimulatorX (MSI)/SimObjects";
|
||||
// "p:/temp/SimObjects"
|
||||
}
|
||||
|
||||
CAircraftModelList CSimulatorFsCommon::getInstalledModels() const
|
||||
{
|
||||
if (!mapperInstance()) { return CAircraftModelList(); }
|
||||
return mapperInstance()->getAircraftCfgEntriesList().toAircraftModelList();
|
||||
}
|
||||
|
||||
CPixmap CSimulatorFsCommon::iconForModel(const QString &modelString) const
|
||||
{
|
||||
static const CPixmap empty;
|
||||
if (modelString.isEmpty() || !mapperInstance()->isInitialized()) { return empty; }
|
||||
CAircraftCfgEntriesList cfgEntries = mapperInstance()->getAircraftCfgEntriesList().findByTitle(modelString);
|
||||
if (cfgEntries.isEmpty())
|
||||
{
|
||||
CLogMessage(this).warning("No .cfg entry for '%1'") << modelString;
|
||||
return empty;
|
||||
}
|
||||
|
||||
// normally we should have only one entry
|
||||
if (cfgEntries.size() > 1)
|
||||
{
|
||||
CLogMessage(this).warning("Multiple FSX .cfg entries for '%1'") << modelString;
|
||||
}
|
||||
|
||||
// use first with icon
|
||||
for (const CAircraftCfgEntries &entry : cfgEntries)
|
||||
{
|
||||
const QString thumbnail = entry.getThumbnailFileName();
|
||||
if (thumbnail.isEmpty()) { continue; }
|
||||
QPixmap pm;
|
||||
if (pm.load(thumbnail))
|
||||
{
|
||||
return CPixmap(pm);
|
||||
}
|
||||
}
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
109
src/plugins/simulator/fscommon/simulator_fscommon.h
Normal file
109
src/plugins/simulator/fscommon/simulator_fscommon.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift Project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKSIMPLUGIN_SIMULATOR_COMMON_H
|
||||
#define BLACKSIMPLUGIN_SIMULATOR_COMMON_H
|
||||
|
||||
#include "blackcore/simulator.h"
|
||||
#include "blacksim/fscommon/aircraftmapper.h"
|
||||
#include "fsuipc.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace FsCommon
|
||||
{
|
||||
//! Common base class for MS flight simulators
|
||||
class CSimulatorFsCommon : public BlackCore::ISimulator, public BlackMisc::Simulation::COwnAircraftProviderSupport
|
||||
{
|
||||
public:
|
||||
//! Destructor
|
||||
virtual ~CSimulatorFsCommon();
|
||||
|
||||
//! \copydoc ISimulator::disconnectFrom()
|
||||
virtual bool disconnectFrom() override;
|
||||
|
||||
//! FSUIPC connected?
|
||||
bool isFsuipcConnected() const;
|
||||
|
||||
//! Experimental model matching
|
||||
static BlackMisc::Simulation::CAircraftModel modelMatching(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft);
|
||||
|
||||
//! SimObjects directory
|
||||
static QString simObjectsDir();
|
||||
|
||||
public slots:
|
||||
|
||||
//! \copydoc ISimulator::isPaused
|
||||
virtual bool isPaused() const override { return m_simPaused; }
|
||||
|
||||
//! \copydoc ISimulator::isTimeSynchronized
|
||||
virtual bool isTimeSynchronized() const override { return m_simTimeSynced; }
|
||||
|
||||
//! \copydoc ISimulator::getTimeSynchronizationOffset
|
||||
virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override;
|
||||
|
||||
//! \copydoc ISimulator::setTimeSynchronization
|
||||
virtual void setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset) override;
|
||||
|
||||
//! \copydoc ISimulator::getSimulatorInfo
|
||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getRemoteAircraft
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override;
|
||||
|
||||
//! \copydoc ISimulator::getAirportsInRange
|
||||
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getInstalledModels
|
||||
virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override;
|
||||
|
||||
//! \copydoc IContextSimulator::iconForModel
|
||||
virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
CSimulatorFsCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr);
|
||||
|
||||
QString simulatorDetails; //!< describes version etc.
|
||||
BlackSim::CSimulatorInfo m_simulatorInfo; //!< about the simulator
|
||||
QScopedPointer<FsCommon::CFsuipc> m_fsuipc; //!< FSUIPC
|
||||
bool m_simPaused = false; //!< Simulator paused?
|
||||
bool m_simTimeSynced = false; //!< Time synchronized?
|
||||
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; //!< time offset
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft; //!< mapped models
|
||||
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< airports in range
|
||||
|
||||
// cockpit as set in SIM
|
||||
BlackMisc::Aviation::CComSystem m_simCom1; //!< cockpit COM1 state in simulator
|
||||
BlackMisc::Aviation::CComSystem m_simCom2; //!< cockpit COM2 state in simulator
|
||||
BlackMisc::Aviation::CTransponder m_simTransponder; //!< cockpit xpdr state in simulator
|
||||
|
||||
//! Set own model
|
||||
void setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model);
|
||||
|
||||
//! Own aircraft has to be be changed
|
||||
void setOwnAircraftModel(const QString &modelName);
|
||||
|
||||
//! Get the mapper singleton
|
||||
static BlackSim::FsCommon::CAircraftMapper *mapperInstance();
|
||||
|
||||
protected slots:
|
||||
|
||||
//! Mapper has been initialized
|
||||
void ps_mapperInitialized(bool success);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "simulator_fsx.h"
|
||||
#include "simconnect_datadefinition.h"
|
||||
#include "blacksim/fscommon/bcdconversions.h"
|
||||
#include "blacksim/fscommon/vpilotmodelmappings.h"
|
||||
#include "blacksim/fscommon/fscommonutil.h"
|
||||
#include "blacksim/fsx/simconnectutilities.h"
|
||||
#include "blacksim/fsx/fsxsimulatorsetup.h"
|
||||
#include "blacksim/simulatorinfo.h"
|
||||
@@ -38,19 +36,13 @@ namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
CSimulatorFsx::CSimulatorFsx(QObject *parent) :
|
||||
ISimulator(parent),
|
||||
m_simulatorInfo(CSimulatorInfo::FSX()),
|
||||
m_fsuipc(new FsCommon::CFsuipc())
|
||||
CSimulatorFsx::CSimulatorFsx(IOwnAircraftProvider *ownAircraft, QObject *parent) :
|
||||
CSimulatorFsCommon(CSimulatorInfo::FSX(), ownAircraft, parent)
|
||||
{
|
||||
Q_ASSERT(ownAircraft);
|
||||
CFsxSimulatorSetup setup;
|
||||
setup.init(); // this fetches important settings on local side
|
||||
this->m_simulatorInfo.setSimulatorSetup(setup.getSettings());
|
||||
|
||||
// hack to init mapper
|
||||
CAircraftMapper *mapper = mapperInstance();
|
||||
connect(mapper, &CAircraftMapper::initCompleted, this, &CSimulatorFsx::ps_mapperInitialized);
|
||||
mapper->initCompletelyInBackground();
|
||||
}
|
||||
|
||||
CSimulatorFsx::~CSimulatorFsx()
|
||||
@@ -68,11 +60,6 @@ namespace BlackSimPlugin
|
||||
return m_simRunning;
|
||||
}
|
||||
|
||||
bool CSimulatorFsx::isFsuipcConnected() const
|
||||
{
|
||||
return m_fsuipc->isConnected();
|
||||
}
|
||||
|
||||
bool CSimulatorFsx::connectTo()
|
||||
{
|
||||
if (m_simConnected) { return true; }
|
||||
@@ -230,103 +217,71 @@ namespace BlackSimPlugin
|
||||
return c;
|
||||
}
|
||||
|
||||
CSimulatorInfo CSimulatorFsx::getSimulatorInfo() const
|
||||
{
|
||||
return this->m_simulatorInfo;
|
||||
}
|
||||
|
||||
void CSimulatorFsx::setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model)
|
||||
{
|
||||
if (m_ownAircraft.getModel() != model)
|
||||
{
|
||||
CAircraftModel newModel(model);
|
||||
if (this->mapperInstance() && this->mapperInstance()->isInitialized())
|
||||
{
|
||||
// reverse lookup of ICAO
|
||||
CAircraftMappingList ml = this->mapperInstance()->getAircraftMappingList().findByModelString(model.getModelString());
|
||||
if (!ml.isEmpty())
|
||||
{
|
||||
CAircraftMapping mapping = ml.front();
|
||||
newModel.setIcao(mapping.getIcao());
|
||||
}
|
||||
}
|
||||
m_ownAircraft.setModel(newModel);
|
||||
emit ownAircraftModelChanged(m_ownAircraft);
|
||||
}
|
||||
}
|
||||
|
||||
bool CSimulatorFsx::updateOwnSimulatorCockpit(const CAircraft &ownAircraft)
|
||||
bool CSimulatorFsx::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
|
||||
{
|
||||
if (originator == this->simulatorOriginator()) { return false; }
|
||||
if (!this->isSimulating()) { return false; }
|
||||
|
||||
// actually those data should be the same as ownAircraft
|
||||
CComSystem newCom1 = ownAircraft.getCom1System();
|
||||
CComSystem newCom2 = ownAircraft.getCom2System();
|
||||
CTransponder newTransponder = ownAircraft.getTransponder();
|
||||
|
||||
bool changed = false;
|
||||
if (newCom1 != this->m_ownAircraft.getCom1System())
|
||||
if (newCom1.getFrequencyActive() != this->m_simCom1.getFrequencyActive())
|
||||
{
|
||||
if (newCom1.getFrequencyActive() != this->m_ownAircraft.getCom1System().getFrequencyActive())
|
||||
{
|
||||
CFrequency newFreq = newCom1.getFrequencyActive();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Active,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
}
|
||||
if (newCom1.getFrequencyStandby() != this->m_ownAircraft.getCom1System().getFrequencyStandby())
|
||||
{
|
||||
CFrequency newFreq = newCom1.getFrequencyStandby();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Standby,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
}
|
||||
this->m_ownAircraft.setCom1System(newCom1);
|
||||
CFrequency newFreq = newCom1.getFrequencyActive();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Active,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
changed = true;
|
||||
|
||||
}
|
||||
if (newCom1.getFrequencyStandby() != this->m_simCom1.getFrequencyStandby())
|
||||
{
|
||||
CFrequency newFreq = newCom1.getFrequencyStandby();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Standby,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (newCom2 != this->m_ownAircraft.getCom2System())
|
||||
if (newCom2.getFrequencyActive() != this->m_simCom2.getFrequencyActive())
|
||||
{
|
||||
if (newCom2.getFrequencyActive() != this->m_ownAircraft.getCom2System().getFrequencyActive())
|
||||
{
|
||||
CFrequency newFreq = newCom2.getFrequencyActive();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Active,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
}
|
||||
if (newCom2.getFrequencyStandby() != this->m_ownAircraft.getCom2System().getFrequencyStandby())
|
||||
{
|
||||
CFrequency newFreq = newCom2.getFrequencyStandby();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Standby,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
}
|
||||
this->m_ownAircraft.setCom2System(newCom2);
|
||||
CFrequency newFreq = newCom2.getFrequencyActive();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Active,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
changed = true;
|
||||
}
|
||||
if (newCom2.getFrequencyStandby() != this->m_simCom2.getFrequencyStandby())
|
||||
{
|
||||
CFrequency newFreq = newCom2.getFrequencyStandby();
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Standby,
|
||||
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
CTransponder xpdr = this->m_ownAircraft.getTransponder();
|
||||
if (newTransponder != xpdr)
|
||||
if (newTransponder.getTransponderCode() != this->m_simTransponder.getTransponderCode())
|
||||
{
|
||||
if (newTransponder.getTransponderCode() != xpdr.getTransponderCode())
|
||||
{
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTransponderCode,
|
||||
CBcdConversions::transponderCodeToBcd(newTransponder), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
changed = true;
|
||||
}
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTransponderCode,
|
||||
CBcdConversions::transponderCodeToBcd(newTransponder), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (newTransponder.getTransponderMode() != xpdr.getTransponderMode())
|
||||
if (newTransponder.getTransponderMode() != this->m_simTransponder.getTransponderMode())
|
||||
{
|
||||
if (m_useSbOffsets)
|
||||
{
|
||||
if (m_useSbOffsets)
|
||||
byte ident = newTransponder.isIdentifying() ? 1 : 0; // 1 is ident
|
||||
byte standby = newTransponder.isInStandby() ? 1 : 0; // 1 is standby
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr += SimConnect_SetClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbIdent, NULL, 0, 1, &ident);
|
||||
hr += SimConnect_SetClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbStandby, NULL, 0, 1, &standby);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
byte ident = newTransponder.isIdentifying() ? 1 : 0; // 1 is ident
|
||||
byte standby = newTransponder.isInStandby() ? 1 : 0; // 1 is standby
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr += SimConnect_SetClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbIdent, NULL, 0, 1, &ident);
|
||||
hr += SimConnect_SetClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbStandby, NULL, 0, 1, &standby);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(this).warning("Setting transponder mode failed (SB offsets)");
|
||||
}
|
||||
CLogMessage(this).warning("Setting transponder mode failed (SB offsets)");
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (changed) { this->m_ownAircraft.setTransponder(newTransponder); }
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// avoid changes of cockpit back to old values due to an outdated read back value
|
||||
@@ -368,58 +323,6 @@ namespace BlackSimPlugin
|
||||
this->displayStatusMessage(message.asStatusMessage(true, true));
|
||||
}
|
||||
|
||||
CAircraftModelList CSimulatorFsx::getInstalledModels() const
|
||||
{
|
||||
if (!mapperInstance()) { return CAircraftModelList(); }
|
||||
return mapperInstance()->getAircraftCfgEntriesList().toAircraftModelList();
|
||||
}
|
||||
|
||||
CSimulatedAircraftList CSimulatorFsx::getRemoteAircraft() const
|
||||
{
|
||||
return this->m_remoteAircraft;
|
||||
}
|
||||
|
||||
CAirportList CSimulatorFsx::getAirportsInRange() const
|
||||
{
|
||||
return this->m_airportsInRange;
|
||||
}
|
||||
|
||||
void CSimulatorFsx::setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset)
|
||||
{
|
||||
this->m_simTimeSynced = enable;
|
||||
this->m_syncTimeOffset = offset;
|
||||
}
|
||||
|
||||
CPixmap CSimulatorFsx::iconForModel(const QString &modelString) const
|
||||
{
|
||||
static const CPixmap empty;
|
||||
if (modelString.isEmpty() || !mapperInstance()->isInitialized()) { return empty; }
|
||||
CAircraftCfgEntriesList cfgEntries = mapperInstance()->getAircraftCfgEntriesList().findByTitle(modelString);
|
||||
if (cfgEntries.isEmpty())
|
||||
{
|
||||
CLogMessage(this).warning("No FSX .cfg entry for '%1'") << modelString;
|
||||
return empty;
|
||||
}
|
||||
|
||||
// normally we should have only one entry
|
||||
if (cfgEntries.size() > 1)
|
||||
{
|
||||
CLogMessage(this).warning("Multiple FSX .cfg entries for '%1'") << modelString;
|
||||
}
|
||||
|
||||
// use first with icon
|
||||
for (const CAircraftCfgEntries &entry : cfgEntries)
|
||||
{
|
||||
const QString thumbnail = entry.getThumbnailFileName();
|
||||
if (thumbnail.isEmpty()) { continue; }
|
||||
QPixmap pm;
|
||||
if (pm.load(thumbnail))
|
||||
{
|
||||
return CPixmap(pm);
|
||||
}
|
||||
}
|
||||
return empty;
|
||||
}
|
||||
|
||||
void CSimulatorFsx::onSimRunning()
|
||||
{
|
||||
@@ -478,7 +381,7 @@ namespace BlackSimPlugin
|
||||
this->onSimStopped();
|
||||
}
|
||||
|
||||
void CSimulatorFsx::updateOwnAircraftFromSim(DataDefinitionOwnAircraft simulatorOwnAircraft)
|
||||
void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft)
|
||||
{
|
||||
BlackMisc::Geo::CCoordinateGeodetic position;
|
||||
position.setLatitude(CLatitude(simulatorOwnAircraft.latitude, CAngleUnit::deg()));
|
||||
@@ -491,11 +394,11 @@ namespace BlackSimPlugin
|
||||
aircraftSituation.setHeading(CHeading(simulatorOwnAircraft.trueHeading, CHeading::True, CAngleUnit::deg()));
|
||||
aircraftSituation.setGroundspeed(CSpeed(simulatorOwnAircraft.velocity, CSpeedUnit::kts()));
|
||||
aircraftSituation.setAltitude(CAltitude(simulatorOwnAircraft.altitude, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||
m_ownAircraft.setSituation(aircraftSituation);
|
||||
ownAircraft().setSituation(aircraftSituation);
|
||||
|
||||
CComSystem com1 = m_ownAircraft.getCom1System(); // set defaults
|
||||
CComSystem com2 = m_ownAircraft.getCom2System();
|
||||
CTransponder transponder = m_ownAircraft.getTransponder();
|
||||
CComSystem com1 = ownAircraft().getCom1System(); // set defaults
|
||||
CComSystem com2 = ownAircraft().getCom2System();
|
||||
CTransponder transponder = ownAircraft().getTransponder();
|
||||
|
||||
// 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.
|
||||
@@ -504,14 +407,21 @@ namespace BlackSimPlugin
|
||||
{
|
||||
com1.setFrequencyActive(CFrequency(simulatorOwnAircraft.com1ActiveMHz, CFrequencyUnit::MHz()));
|
||||
com1.setFrequencyStandby(CFrequency(simulatorOwnAircraft.com1StandbyMHz, CFrequencyUnit::MHz()));
|
||||
m_ownAircraft.setCom1System(com1);
|
||||
bool changedCom1 = ownAircraft().getCom1System() != com1;
|
||||
this->m_simCom1 = com1;
|
||||
|
||||
com2.setFrequencyActive(CFrequency(simulatorOwnAircraft.com2ActiveMHz, CFrequencyUnit::MHz()));
|
||||
com2.setFrequencyStandby(CFrequency(simulatorOwnAircraft.com2StandbyMHz, CFrequencyUnit::MHz()));
|
||||
m_ownAircraft.setCom2System(com2);
|
||||
bool changedCom2 = ownAircraft().getCom2System() != com2;
|
||||
this->m_simCom2 = com2;
|
||||
|
||||
transponder.setTransponderCode(simulatorOwnAircraft.transponderCode);
|
||||
m_ownAircraft.setTransponder(transponder);
|
||||
bool changedXpr = (ownAircraft().getTransponderCode() != transponder.getTransponderCode());
|
||||
|
||||
if (changedCom1 || changedCom2 || changedXpr)
|
||||
{
|
||||
this->providerUpdateCockpit(com1, com2, transponder, simulatorOriginator());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -519,16 +429,22 @@ namespace BlackSimPlugin
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorFsx::updateOwnAircraftFromSim(DataDefinitionClientAreaSb sbDataArea)
|
||||
void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionClientAreaSb sbDataArea)
|
||||
{
|
||||
CTransponder::TransponderMode newMode;
|
||||
if (sbDataArea.isIdent())
|
||||
{
|
||||
this->m_ownAircraft.setTransponderMode(CTransponder::StateIdent);
|
||||
newMode = CTransponder::StateIdent;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_ownAircraft.setTransponderMode(sbDataArea.isStandby() ? CTransponder::StateStandby : CTransponder::ModeC);
|
||||
newMode = sbDataArea.isStandby() ? CTransponder::StateStandby : CTransponder::ModeC;
|
||||
}
|
||||
bool changed = (this->ownAircraft().getTransponderMode() != newMode);
|
||||
if (!changed) { return; }
|
||||
CTransponder xpdr = this->ownAircraft().getTransponder();
|
||||
xpdr.setTransponderMode(newMode);
|
||||
this->providerUpdateCockpit(ownAircraft().getCom1System(), ownAircraft().getCom2System(), xpdr, this->simulatorOriginator());
|
||||
}
|
||||
|
||||
void CSimulatorFsx::setSimConnectObjectID(DWORD requestID, DWORD objectID)
|
||||
@@ -563,7 +479,16 @@ namespace BlackSimPlugin
|
||||
void CSimulatorFsx::ps_dispatch()
|
||||
{
|
||||
SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this);
|
||||
if (this->m_fsuipc) this->m_fsuipc->process();
|
||||
if (m_fsuipc)
|
||||
{
|
||||
CSimulatedAircraft fsuipcAircraft(ownAircraft());
|
||||
bool ok = m_fsuipc->read(fsuipcAircraft);
|
||||
if (ok)
|
||||
{
|
||||
// do whatever is required
|
||||
Q_UNUSED(fsuipcAircraft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorFsx::ps_connectToFinished()
|
||||
@@ -586,11 +511,6 @@ namespace BlackSimPlugin
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorFsx::ps_mapperInitialized(bool success)
|
||||
{
|
||||
if (success) { emit this->installedAircraftModelsChanged(); }
|
||||
}
|
||||
|
||||
void CSimulatorFsx::removeRemoteAircraft(const CSimConnectObject &simObject)
|
||||
{
|
||||
SimConnect_AIRemoveObject(m_hSimConnect, simObject.getObjectId(), simObject.getRequestId());
|
||||
@@ -748,99 +668,5 @@ namespace BlackSimPlugin
|
||||
CLogMessage(this).info("Synchronized time to UTC: %1") << myTime.toString();
|
||||
}
|
||||
}
|
||||
|
||||
CAircraftMapper *CSimulatorFsx::mapperInstance()
|
||||
{
|
||||
static CAircraftMapper *mapper = new CAircraftMapper(
|
||||
std::unique_ptr<CVPilotModelMappings>(new CVPilotModelMappings(true)), // currently hard wired
|
||||
simObjectsDir()
|
||||
);
|
||||
return mapper;
|
||||
}
|
||||
|
||||
CAircraftModel CSimulatorFsx::modelMatching(const CSimulatedAircraft &remoteAircraft)
|
||||
{
|
||||
|
||||
// Manually set string?
|
||||
if (remoteAircraft.getModel().hasManuallySetString())
|
||||
{
|
||||
// manual set model
|
||||
return remoteAircraft.getModel();
|
||||
}
|
||||
|
||||
// default model
|
||||
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");
|
||||
CLogMessage(static_cast<CSimulatorFsx *>(nullptr)).warning("Mapper not ready, set to default model");
|
||||
return aircraftModel;
|
||||
}
|
||||
|
||||
// Model by queried string
|
||||
const CClient remoteClient = remoteAircraft.getClient();
|
||||
if (remoteClient.getAircraftModel().hasQueriedModelString())
|
||||
{
|
||||
QString directModelString = remoteClient.getAircraftModel().getModelString();
|
||||
if (!directModelString.isEmpty() && mapperInstance()->containsModelWithTitle(directModelString))
|
||||
{
|
||||
aircraftModel = mapperInstance()->getModelWithTitle(directModelString);
|
||||
aircraftModel.setModelType(CAircraftModel::TypeQueriedFromNetwork);
|
||||
}
|
||||
}
|
||||
|
||||
// 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");
|
||||
aircraftModel.setModelType(CAircraftModel::TypeModelMatching);
|
||||
}
|
||||
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());
|
||||
Q_ASSERT(aircraftModel.getModelType() != CAircraftModel::TypeUnknown);
|
||||
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
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
|
||||
#include "simconnect_datadefinition.h"
|
||||
#include "simconnect_object.h"
|
||||
#include "../fscommon/fsuipc.h"
|
||||
#include "../fscommon/simulator_fscommon.h"
|
||||
#include "blackcore/simulator.h"
|
||||
#include "blackcore/interpolator_linear.h"
|
||||
#include "blacksim/simulatorinfo.h"
|
||||
#include "blacksim/fscommon/aircraftmapper.h"
|
||||
#include "blackmisc/simulation/aircraftmodel.h"
|
||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||
#include "blackmisc/avairportlist.h"
|
||||
@@ -67,13 +66,13 @@ namespace BlackSimPlugin
|
||||
};
|
||||
|
||||
//! FSX Simulator Implementation
|
||||
class CSimulatorFsx : public BlackCore::ISimulator
|
||||
class CSimulatorFsx : public BlackSimPlugin::FsCommon::CSimulatorFsCommon
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
CSimulatorFsx(QObject *parent = nullptr);
|
||||
CSimulatorFsx(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CSimulatorFsx();
|
||||
@@ -84,9 +83,6 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::isSimulating
|
||||
virtual bool isSimulating() const override;
|
||||
|
||||
//! FSUIPC connected?
|
||||
bool isFsuipcConnected() const;
|
||||
|
||||
//! \copydoc ISimulator::canConnect()
|
||||
virtual bool canConnect() const override;
|
||||
|
||||
@@ -104,9 +100,6 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::disconnectFrom()
|
||||
virtual bool disconnectFrom() override;
|
||||
|
||||
//! \copydoc ISimulator::getOwnAircraft()
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const override { return m_ownAircraft; }
|
||||
|
||||
//! \copydoc ISimulator::addRemoteAircraft()
|
||||
virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
|
||||
|
||||
@@ -119,11 +112,8 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::changeRemoteAircraft
|
||||
virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &toChangeAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override;
|
||||
|
||||
//! \copydoc ISimulator::getSimulatorInfo()
|
||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
|
||||
|
||||
//! \copydoc ISimulator::updateOwnCockpit
|
||||
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft) override;
|
||||
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft, const QString &originator) override;
|
||||
|
||||
//! \copydoc ISimulator::displayStatusMessage
|
||||
virtual void displayStatusMessage(const BlackMisc::CStatusMessage &message) const override;
|
||||
@@ -131,33 +121,6 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::displayTextMessage()
|
||||
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
|
||||
|
||||
//! \copydoc ISimulator::getAircraftModel()
|
||||
virtual BlackMisc::Simulation::CAircraftModel getOwnAircraftModel() const override { return m_ownAircraft.getModel(); }
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getInstalledModels
|
||||
virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getRemoteAircraft
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override;
|
||||
|
||||
//! \copydoc ISimulator::getAirportsInRange
|
||||
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
|
||||
|
||||
//! \copydoc ISimulator::setTimeSynchronization
|
||||
virtual void setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset) override;
|
||||
|
||||
//! \copydoc ISimulator::isTimeSynchronized
|
||||
virtual bool isTimeSynchronized() const override { return m_simTimeSynced; }
|
||||
|
||||
//! \copydoc ISimulator::getTimeSynchronizationOffset
|
||||
virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override { return m_syncTimeOffset; }
|
||||
|
||||
//! \copydoc ISimulator::isPaused
|
||||
virtual bool isPaused() const override { return m_simPaused; }
|
||||
|
||||
//! \copydoc IContextSimulator::iconForModel
|
||||
virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override;
|
||||
|
||||
//! Called when sim has started
|
||||
void onSimRunning();
|
||||
|
||||
@@ -168,10 +131,10 @@ namespace BlackSimPlugin
|
||||
void onSimFrame();
|
||||
|
||||
//! Called when data about our own aircraft are received
|
||||
void updateOwnAircraftFromSim(DataDefinitionOwnAircraft simulatorOwnAircraft);
|
||||
void updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft);
|
||||
|
||||
//! Update from SB client area
|
||||
void updateOwnAircraftFromSim(DataDefinitionClientAreaSb sbDataArea);
|
||||
void updateOwnAircraftFromSimulator(DataDefinitionClientAreaSb sbDataArea);
|
||||
|
||||
//! Set ID of a SimConnect object
|
||||
void setSimConnectObjectID(DWORD requestID, DWORD objectID);
|
||||
@@ -179,9 +142,6 @@ namespace BlackSimPlugin
|
||||
//! \private
|
||||
void onSimExit();
|
||||
|
||||
//! \private
|
||||
void setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model);
|
||||
|
||||
protected:
|
||||
//! Timer event
|
||||
virtual void timerEvent(QTimerEvent *event);
|
||||
@@ -194,9 +154,6 @@ namespace BlackSimPlugin
|
||||
//! Called when asynchronous connection to Simconnect has finished
|
||||
void ps_connectToFinished();
|
||||
|
||||
//! Mapper has been initialized
|
||||
void ps_mapperInitialized(bool success);
|
||||
|
||||
private:
|
||||
|
||||
//! Remove a remote aircraft
|
||||
@@ -220,36 +177,18 @@ namespace BlackSimPlugin
|
||||
//! Sync time with user's computer
|
||||
void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim);
|
||||
|
||||
//! Get the mapper singleton
|
||||
static BlackSim::FsCommon::CAircraftMapper *mapperInstance();
|
||||
|
||||
//! Experimental model matching
|
||||
static BlackMisc::Simulation::CAircraftModel modelMatching(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft);
|
||||
|
||||
//! 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; //!< Timer identifier
|
||||
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; //!< Time offset (if synchronized)
|
||||
QString simulatorDetails; //!< describes version etc.
|
||||
BlackSim::CSimulatorInfo m_simulatorInfo; //!< about the simulator
|
||||
BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft; //!< mapped models
|
||||
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< airports in range
|
||||
|
||||
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; //!< Time offset (if synchronized)
|
||||
QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
|
||||
QFutureWatcher<bool> m_watcherConnect;
|
||||
QScopedPointer<FsCommon::CFsuipc> m_fsuipc;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace BlackSimPlugin
|
||||
{
|
||||
DataDefinitionOwnAircraft *ownAircaft;
|
||||
ownAircaft = (DataDefinitionOwnAircraft *)&pObjData->dwData;
|
||||
simulatorFsx->updateOwnAircraftFromSim(*ownAircaft);
|
||||
simulatorFsx->updateOwnAircraftFromSimulator(*ownAircaft);
|
||||
break;
|
||||
}
|
||||
case CSimConnectDefinitions::RequestOwnAircraftTitle:
|
||||
@@ -162,19 +162,19 @@ namespace BlackSimPlugin
|
||||
case SIMCONNECT_RECV_ID_AIRPORT_LIST:
|
||||
{
|
||||
const CLength maxDistance(200.0, CLengthUnit::NM());
|
||||
const CCoordinateGeodetic posAircraft = simulatorFsx->getOwnAircraft().getPosition();
|
||||
const CCoordinateGeodetic posAircraft = simulatorFsx->ownAircraft().getPosition();
|
||||
SIMCONNECT_RECV_AIRPORT_LIST *pAirportList = (SIMCONNECT_RECV_AIRPORT_LIST *) pData;
|
||||
for (unsigned i = 0; i < pAirportList->dwArraySize; ++i)
|
||||
{
|
||||
SIMCONNECT_DATA_FACILITY_AIRPORT *pFacilityAirport = pAirportList->rgData + i;
|
||||
if (!pFacilityAirport) break;
|
||||
const QString icao(pFacilityAirport->Icao);
|
||||
if (icao.isEmpty()) continue; // airfield without ICAO code
|
||||
if (icao.isEmpty()) { continue; } // airfield without ICAO code
|
||||
if (!CAirportIcao::isValidIcaoDesignator(icao)) continue; // tiny airfields in SIM
|
||||
CCoordinateGeodetic pos(pFacilityAirport->Latitude, pFacilityAirport->Longitude, pFacilityAirport->Altitude);
|
||||
CAirport airport(CAirportIcao(icao), pos);
|
||||
CLength d = airport.calculcateDistanceAndBearingToOwnAircraft(posAircraft);
|
||||
if (d > maxDistance) continue;
|
||||
if (d > maxDistance) { continue; }
|
||||
simulatorFsx->m_airportsInRange.replaceOrAddByIcao(airport);
|
||||
}
|
||||
if (simulatorFsx->m_airportsInRange.size() > 20)
|
||||
@@ -192,7 +192,7 @@ namespace BlackSimPlugin
|
||||
//! \todo why is offset 19 ident 2/0 ?
|
||||
//! In FSUIPC it is 0/1, according to documentation it is 0/1 but I receive 2/0 here
|
||||
DataDefinitionClientAreaSb *sbData = (DataDefinitionClientAreaSb *) &clientData->dwData;
|
||||
simulatorFsx->updateOwnAircraftFromSim(*sbData);
|
||||
simulatorFsx->updateOwnAircraftFromSimulator(*sbData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,10 @@ namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
BlackCore::ISimulator *CSimulatorFsxFactory::create(QObject *parent)
|
||||
BlackCore::ISimulator *CSimulatorFsxFactory::create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent)
|
||||
{
|
||||
return new CSimulatorFsx(parent);
|
||||
Q_ASSERT(ownAircraft);
|
||||
return new CSimulatorFsx(ownAircraft, parent);
|
||||
}
|
||||
|
||||
CSimulatorInfo CSimulatorFsxFactory::getSimulatorInfo() const
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace BlackSimPlugin
|
||||
|
||||
public:
|
||||
//! \copydoc BlackCore::ISimulatorFactory::create
|
||||
virtual BlackCore::ISimulator *create(QObject *parent) override;
|
||||
virtual BlackCore::ISimulator *create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent) override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulatorFactory::getSimulatorInfo
|
||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
/* 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/. */
|
||||
/* Copyright (C) 2013
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "simulator_xplane.h"
|
||||
#include "xbus_service_proxy.h"
|
||||
@@ -23,7 +27,8 @@ namespace BlackSimPlugin
|
||||
namespace XPlane
|
||||
{
|
||||
|
||||
CSimulatorXPlane::CSimulatorXPlane(QObject *parent) : BlackCore::ISimulator(parent)
|
||||
CSimulatorXPlane::CSimulatorXPlane(IOwnAircraftProvider *ownAircraft, QObject *parent) :
|
||||
BlackCore::ISimulator(parent), COwnAircraftProviderSupport(ownAircraft)
|
||||
{
|
||||
m_watcher = new QDBusServiceWatcher(this);
|
||||
m_watcher->setWatchMode(QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration);
|
||||
@@ -164,15 +169,14 @@ namespace BlackSimPlugin
|
||||
void CSimulatorXPlane::ps_emitOwnAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao)
|
||||
{
|
||||
//! \todo change as appropriate
|
||||
CSimulatedAircraft aircraft(this->getOwnAircraft());
|
||||
CAircraftModel model(aircraft.getModel());
|
||||
CAircraftModel model(ownAircraft().getModel());
|
||||
model.setModelType(CAircraftModel::TypeOwnSimulatorModel);
|
||||
model.setFileName(path + "/" + filename);
|
||||
CAircraftIcao aircraftIcao(icao);
|
||||
aircraftIcao.setLivery(livery);
|
||||
aircraft.setModel(model);
|
||||
aircraft.setIcaoInfo(aircraftIcao);
|
||||
emit ownAircraftModelChanged(aircraft);
|
||||
ownAircraft().setIcaoInfo(aircraftIcao);
|
||||
ownAircraft().setModel(model);
|
||||
emit ownAircraftModelChanged(ownAircraft());
|
||||
}
|
||||
|
||||
// convert xplane squawk mode to swift squawk mode
|
||||
@@ -188,7 +192,7 @@ namespace BlackSimPlugin
|
||||
return mode == BlackMisc::Aviation::CTransponder::StateStandby ? 1 : 2;
|
||||
}
|
||||
|
||||
CSimulatedAircraft CSimulatorXPlane::getOwnAircraft() const
|
||||
CSimulatedAircraft CSimulatorXPlane::xplaneDataToSimulatedAircraft() const
|
||||
{
|
||||
if (! isConnected()) { return {}; }
|
||||
Aviation::CAircraftSituation situation;
|
||||
@@ -198,9 +202,8 @@ namespace BlackSimPlugin
|
||||
situation.setPitch({ m_xplaneData.pitch, CAngleUnit::deg() });
|
||||
situation.setBank({ m_xplaneData.roll, CAngleUnit::deg() });
|
||||
situation.setGroundspeed({ m_xplaneData.groundspeed, CSpeedUnit::m_s() });
|
||||
CSimulatedAircraft ac;
|
||||
CSimulatedAircraft ac(ownAircraft());
|
||||
ac.setSituation(situation);
|
||||
ac.setModel(this->getOwnAircraftModel());
|
||||
ac.setIcaoInfo(Aviation::CAircraftIcao { m_xplaneData.aircraftIcaoCode });
|
||||
ac.setCom1System(Aviation::CComSystem::getCom1System({ m_xplaneData.com1Active, CFrequencyUnit::kHz() }, { m_xplaneData.com1Standby, CFrequencyUnit::kHz() }));
|
||||
ac.setCom2System(Aviation::CComSystem::getCom2System({ m_xplaneData.com2Active, CFrequencyUnit::kHz() }, { m_xplaneData.com2Standby, CFrequencyUnit::kHz() }));
|
||||
@@ -222,12 +225,6 @@ namespace BlackSimPlugin
|
||||
Q_UNUSED(message);
|
||||
}
|
||||
|
||||
BlackMisc::Simulation::CAircraftModel CSimulatorXPlane::getOwnAircraftModel() const
|
||||
{
|
||||
if (! isConnected()) { return {}; }
|
||||
return { m_xplaneData.aircraftModelPath, CAircraftModel::TypeOwnSimulatorModel };
|
||||
}
|
||||
|
||||
BlackMisc::Simulation::CAircraftModelList CSimulatorXPlane::getInstalledModels() const
|
||||
{
|
||||
// TODO
|
||||
@@ -276,11 +273,10 @@ namespace BlackSimPlugin
|
||||
return CPixmap();
|
||||
}
|
||||
|
||||
bool CSimulatorXPlane::updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft)
|
||||
bool CSimulatorXPlane::updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft, const QString &originator)
|
||||
{
|
||||
if (! isConnected()) { return false; }
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
if (originator == this->simulatorOriginator()) { return false; }
|
||||
if (!isConnected()) { return false; }
|
||||
auto com1 = Aviation::CComSystem::getCom1System({ m_xplaneData.com1Active, CFrequencyUnit::kHz() }, { m_xplaneData.com1Standby, CFrequencyUnit::kHz() });
|
||||
auto com2 = Aviation::CComSystem::getCom2System({ m_xplaneData.com2Active, CFrequencyUnit::kHz() }, { m_xplaneData.com2Standby, CFrequencyUnit::kHz() });
|
||||
auto xpdr = Aviation::CTransponder::getStandardTransponder(m_xplaneData.xpdrCode, xpdrMode(m_xplaneData.xpdrMode, m_xplaneData.xpdrIdent));
|
||||
@@ -345,5 +341,10 @@ namespace BlackSimPlugin
|
||||
//! \todo really update aircraft in SIM
|
||||
}
|
||||
|
||||
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(IOwnAircraftProvider *ownAircraft, QObject *parent)
|
||||
{
|
||||
return new CSimulatorXPlane(ownAircraft, parent);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define BLACKSIMPLUGIN_SIMULATOR_XPLANE_H
|
||||
|
||||
#include "blackcore/simulator.h"
|
||||
#include "blackmisc/simulation/simdirectaccessownaircraft.h"
|
||||
#include "blackmisc/pixmap.h"
|
||||
#include <QDBusConnection>
|
||||
|
||||
@@ -29,13 +30,13 @@ namespace BlackSimPlugin
|
||||
/*!
|
||||
* X-Plane ISimulator implementation
|
||||
*/
|
||||
class CSimulatorXPlane : public BlackCore::ISimulator
|
||||
class CSimulatorXPlane : public BlackCore::ISimulator, BlackMisc::Simulation::COwnAircraftProviderSupport
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
CSimulatorXPlane(QObject *parent = nullptr);
|
||||
CSimulatorXPlane(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr);
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::isConnected
|
||||
virtual bool isConnected() const override;
|
||||
@@ -62,9 +63,6 @@ namespace BlackSimPlugin
|
||||
//! \copydoc BlackCore::ISimulator::disconnectFrom
|
||||
virtual bool disconnectFrom() override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getOwnAircraft
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const override;
|
||||
|
||||
//! \copydoc ISimulator::addRemoteAircraft()
|
||||
virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
|
||||
|
||||
@@ -82,7 +80,7 @@ namespace BlackSimPlugin
|
||||
virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::updateOwnSimulatorCockpit
|
||||
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft) override;
|
||||
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft, const QString &originator) override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getSimulatorInfo
|
||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override { return BlackSim::CSimulatorInfo::XP(); }
|
||||
@@ -93,9 +91,6 @@ namespace BlackSimPlugin
|
||||
//! \copydoc ISimulator::displayTextMessage
|
||||
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getAircraftModel
|
||||
virtual BlackMisc::Simulation::CAircraftModel getOwnAircraftModel() const override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::getInstalledModels
|
||||
virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override;
|
||||
|
||||
@@ -130,6 +125,8 @@ namespace BlackSimPlugin
|
||||
BlackMisc::Aviation::CAirportList m_airports;
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft;
|
||||
|
||||
BlackMisc::Simulation::CSimulatedAircraft xplaneDataToSimulatedAircraft() const;
|
||||
|
||||
//! \todo Add units to members? pitchDeg?, altitudeFt?
|
||||
struct // data is written by DBus async method callbacks
|
||||
{
|
||||
@@ -166,7 +163,7 @@ namespace BlackSimPlugin
|
||||
|
||||
public:
|
||||
//! \copydoc BlackCore::ISimulatorFactory::create
|
||||
virtual BlackCore::ISimulator *create(QObject *parent = nullptr) override { return new CSimulatorXPlane(parent); }
|
||||
virtual BlackCore::ISimulator *create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr) override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulatorFactory::getSimulatorInfo
|
||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override { return BlackSim::CSimulatorInfo::XP(); }
|
||||
|
||||
Reference in New Issue
Block a user