From 6439431030ca548c99bbf7c790bbcd27fc73d8dc Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Fri, 14 Mar 2014 18:55:11 +0100 Subject: [PATCH] Add methods to add and remove remote aircrafts/situations Extend gear to 100 % by default. Aircraft is default B737 refs #186 --- src/blackcore/fsx/simulator_fsx.cpp | 116 ++++++++++++++++++++++++++-- src/blackcore/fsx/simulator_fsx.h | 34 +++++++- src/blackcore/simulator.h | 21 +++++ 3 files changed, 163 insertions(+), 8 deletions(-) diff --git a/src/blackcore/fsx/simulator_fsx.cpp b/src/blackcore/fsx/simulator_fsx.cpp index a6b7e6c68..3e8cb7942 100644 --- a/src/blackcore/fsx/simulator_fsx.cpp +++ b/src/blackcore/fsx/simulator_fsx.cpp @@ -20,7 +20,8 @@ namespace BlackCore ISimulator(parent), m_isConnected(false), m_simRunning(false), - m_hSimConnect(nullptr) + m_hSimConnect(nullptr), + m_nextObjID(1) { QTimer::singleShot(5000, this, SLOT(checkConnection())); } @@ -30,6 +31,50 @@ namespace BlackCore return m_isConnected; } + void CSimulatorFSX::addRemoteAircraft(const CCallsign &callsign, const QString &type, const CAircraftSituation &initialSituation) + { + HRESULT hr = S_OK; + Q_UNUSED(type); + + SIMCONNECT_DATA_INITPOSITION initialPosition; + initialPosition.Latitude = initialSituation.latitude().value(); + initialPosition.Longitude = initialSituation.longitude().value(); + initialPosition.Altitude = initialSituation.getAltitude().value(); + initialPosition.Pitch = initialSituation.getPitch().value(); + initialPosition.Bank = initialSituation.getBank().value(); + initialPosition.Heading = initialSituation.getHeading().value(); + initialPosition.Airspeed = 0; + initialPosition.OnGround = 0; + + SimConnectObject simObj; + simObj.m_callsign = callsign; + simObj.m_requestId = m_nextObjID; + simObj.m_objectId = 0; + simObj.m_interpolator.addAircraftSituation(initialSituation); + m_simConnectObjects.insert(callsign, simObj); + ++m_nextObjID; + + hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, "Boeing 737-800 Paint1", callsign.toQString().left(12).toLatin1().constData(), initialPosition, simObj.m_requestId); + } + + void CSimulatorFSX::addAircraftSituation(const CCallsign &callsign, const CAircraftSituation & situation) + { + if (!m_simConnectObjects.contains(callsign)) + { + addRemoteAircraft(callsign, "Boeing 737-800 Paint1", situation); + return; + } + + SimConnectObject simObj = m_simConnectObjects.value(callsign); + simObj.m_interpolator.addAircraftSituation(situation); + m_simConnectObjects.insert(callsign, simObj); + } + + void CSimulatorFSX::removeRemoteAircraft(const CCallsign &callsign) + { + // TODO + } + void CALLBACK CSimulatorFSX::SimConnectProc(SIMCONNECT_RECV* pData, DWORD /* cbData */, void *pContext) { CSimulatorFSX *simulatorFsx = static_cast(pContext); @@ -94,8 +139,8 @@ namespace BlackCore switch(pObjData->dwRequestID) { case CSimConnectDataDefinition::RequestOwnAircraft: - OwnAircraft *ownAircaft; - ownAircaft = (OwnAircraft*)&pObjData->dwData; + DataDefinitionOwnAircraft *ownAircaft; + ownAircaft = (DataDefinitionOwnAircraft*)&pObjData->dwData; simulatorFsx->setOwnAircraft(*ownAircaft); break; } @@ -127,7 +172,7 @@ namespace BlackCore } - void CSimulatorFSX::setOwnAircraft(OwnAircraft aircraft) + void CSimulatorFSX::setOwnAircraft(DataDefinitionOwnAircraft aircraft) { BlackMisc::Geo::CCoordinateGeodetic position; position.setLatitude(CLatitude(aircraft.latitude, CAngleUnit::deg())); @@ -157,14 +202,41 @@ namespace BlackCore m_ownAircraft.setTransponder(transponder); } - void CSimulatorFSX::setSimconnectObjectID(DWORD /* requestID */, DWORD /* objectID */) + void CSimulatorFSX::setSimconnectObjectID(DWORD requestID, DWORD objectID) { + SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID); + SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EVENT_FREEZELAT, 1, + SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EVENT_FREEZEALT, 1, + SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EVENT_FREEZEATT, 1, + SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + + DataDefinitionAircraftConfiguration configuration; + configuration.gearCenter = 100.0; + configuration.gearLeft = 100.0; + configuration.gearRight = 100.0; + configuration.gearTail = 100.0; + configuration.gearAux = 100.0; + SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, simObj.m_objectId, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionAircraftConfiguration), &configuration); + + SimConnectObject simObject; + foreach (simObject, m_simConnectObjects) + { + if (simObject.m_requestId == requestID) + { + simObject.m_objectId = objectID; + break; + } + } + m_simConnectObjects.insert(simObject.m_callsign, simObject); } void CSimulatorFSX::timerEvent(QTimerEvent* /* event */) { dispatch(); + update(); } void CSimulatorFSX::checkConnection() @@ -195,6 +267,9 @@ namespace BlackCore hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, EVENT_SIM_STATUS, "Sim"); hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, EVENT_OBJECT_ADDED, "ObjectAdded"); hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, EVENT_OBJECT_REMOVED, "ObjectRemoved"); + hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EVENT_FREEZELAT, "FREEZE_LATITUDE_LONGITUDE_SET"); + hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EVENT_FREEZEALT, "FREEZE_ALTITUDE_SET"); + hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EVENT_FREEZEATT, "FREEZE_ATTITUDE_SET"); return hr; } @@ -203,5 +278,36 @@ namespace BlackCore { return CSimConnectDataDefinition::initDataDefinitions(m_hSimConnect); } + + void CSimulatorFSX::update() + { + foreach (SimConnectObject simObj, m_simConnectObjects) + { + if (simObj.m_interpolator.hasEnoughAircraftSituations()) + { + DataDefinitionAircraftPosition position; + CAircraftSituation situation = simObj.m_interpolator.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.trueHeading = situation.getHeading().value(CAngleUnit::deg()); + + DataDefinitionAircraftConfiguration configuration; + configuration.gearCenter = 100.0; + configuration.gearLeft = 100.0; + configuration.gearRight = 100.0; + configuration.gearTail = 100.0; + configuration.gearAux = 100.0; + + if (simObj.m_objectId != 0) + { + SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, simObj.m_objectId, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionAircraftPosition), &position); + SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, simObj.m_objectId, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionAircraftConfiguration), &configuration); + } + } + } + } } } diff --git a/src/blackcore/fsx/simulator_fsx.h b/src/blackcore/fsx/simulator_fsx.h index 813be5125..263122482 100644 --- a/src/blackcore/fsx/simulator_fsx.h +++ b/src/blackcore/fsx/simulator_fsx.h @@ -6,11 +6,17 @@ #ifndef BLACKCORE_SIMULATOR_FSX_H #define BLACKCORE_SIMULATOR_FSX_H -#include +#define NOMINMAX + #include "simconnect_datadefinition.h" + +#include "blackcore/simulator.h" +#include "blackcore/interpolator_linear.h" #include "blackmisc/avaircraft.h" +#include #include -#include "simconnect/SimConnect.h" +#include + #include namespace BlackCore @@ -43,6 +49,15 @@ namespace BlackCore //! \copydoc ISimulator::getOwnAircraft() virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; } + //! \copydoc ISimulator::addRemoteAircraft() + virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const QString &type, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; + + //! \copydoc ISimulator::addAircraftSituation() + virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; + + //! \copydoc ISimulator::removeRemoteAircraft() + virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; + /*! * \brief SimConnect Callback * \param pData @@ -64,7 +79,7 @@ namespace BlackCore * \brief Called when data about our own aircraft is received * \param aircraft */ - void setOwnAircraft(OwnAircraft aircraft); + void setOwnAircraft(DataDefinitionOwnAircraft aircraft); /*! * \brief Set ID of a SimConnect object @@ -89,6 +104,14 @@ namespace BlackCore private: + struct SimConnectObject + { + BlackMisc::Aviation::CCallsign m_callsign; + BlackCore::CInterpolatorLinear m_interpolator; + int m_requestId; + int m_objectId; + }; + /*! * \brief Initialize SimConnect system events * \return @@ -101,12 +124,17 @@ namespace BlackCore */ HRESULT initDataDefinitions(); + void update(); + bool m_isConnected; //!< Is sim connected bool m_simRunning; //!< Sim running. HANDLE m_hSimConnect; //!< Handle to SimConnect object + uint m_nextObjID; BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator + QHash m_simConnectObjects; + }; } diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 2f09ce202..035e07115 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -46,6 +46,27 @@ namespace BlackCore */ virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const = 0; + /*! + * \brief Add new remote aircraft to the simulator + * \param callsign + * \param type + * \param initialSituation + */ + virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const QString &type, const BlackMisc::Aviation::CAircraftSituation &initialSituation) = 0; + + /*! + * \brief Add new aircraft situation + * \param callsign + * \param initialSituation + */ + virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) = 0; + + /*! + * \brief Remove remote aircraft from simulator + * \param callsign + */ + virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) = 0; + signals: //! \brief Emitted when the connection status has changed void connectionChanged(bool value);